Instead of requiring the user to type in the recipient's number,
the MIDlet allows the user to select the number from the device's
contacts list. This feature is launched from the EventCreationForm
with a separate option, which displays the ContactListForm
. The ContactListForm
contains a list of saved contacts
on the device, and an option for selecting the contact, whose details
are then filled into the EventCreationForm
.
Figure: Selecting the recipient from the contacts list
To implement the ContactListForm
class:
Create the ContactListForm.java
class file.
Import the required
packages, initialize the UI elements and Commands
, and create a CommandListener
.
import java.util.*; import javax.microedition.lcdui.*; import javax.microedition.pim.*; // This Form shows a list of the contacts in the local databases class ContactListForm extends List implements CommandListener { private final Command exitCommand, selectCommand, backCommand; private final EventSharingMIDlet parent; private boolean available; private Vector allTelNumbers = new Vector(); public ContactListForm(EventSharingMIDlet parent) { super("Contacts", Choice.IMPLICIT); this.parent = parent; // init UI selectCommand = new Command("Select", Command.OK, 0); backCommand = new Command("Back", Command.BACK, 1); exitCommand = new Command("Exit", Command.EXIT, 1); addCommand(backCommand); addCommand(exitCommand); setCommandListener(this); setFitPolicy(Choice.TEXT_WRAP_ON); // load the list of names in a different thread parent.enqueueOperation(new LoadContacts()); } public void commandAction(Command cmd, Displayable displayable) { // if no names are available return if (!available) { parent.showMain(); return; } else if (cmd == selectCommand) { int selected = getSelectedIndex(); if (selected >= 0) { // will get the number from the list parent.contactSelected((String)allTelNumbers.elementAt(selected)); } else { parent.showMain(); } } else if (cmd == backCommand) { parent.showMain(); } else if (cmd == exitCommand) { parent.notifyDestroyed(); } }
Create a method
for getting a new instance of the PIM
class, and
use the PIM.openPIMList
method to open the default
list for the used contact list type.
Verify that
the required fields are supported by calling the PIMList.isSupportedField
method. After verification,
read the local database for phone numbers and extract the contact
information, including first and last names (where available), and
telephone numbers.
// loads the names of a named contact list private void loadNames(String name) throws PIMException, SecurityException { ContactList contactList = null; try { contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY, name); // First check that the fields we are interested in are supported // by the PIM List if (contactList.isSupportedField(Contact.NAME) && contactList.isSupportedField(Contact.TEL)) { // Put an informative title while reading the contacts setTitle("Contacts"); Enumeration items = contactList.items(); Vector telNumbers = new Vector(); // For each Contact in the List while (items.hasMoreElements()) { String firstname=null; String lastname=null; Contact contact = (Contact) items.nextElement(); //Get First Name if available try { firstname=contact.getStringArray(Contact.NAME, Contact.ATTR_NONE)[Contact.NAME_GIVEN]; } catch(Exception e){} //Get Last Name if available try { lastname=contact.getStringArray(Contact.NAME, Contact.ATTR_NONE)[Contact.NAME_FAMILY]; } catch(Exception e){} //Counts the number of telephone entries for this contact int telCount=contact.countValues(Contact.TEL);
Continuing in
the loadNames
method, set the appropriate search
criteria. Check the contents of the retrieved contacts to sort out
the data and to fetch only those entries that have phone numbers attached
to them and either a first or last name defined. To verify that a PIMList
supports the attributes you are interested in, use
the isSupportedAttribute
and getSupportedAttributes
methods.
// we're only interested on contacts with a phone number // and a name (either first or last). if (telCount > 0 && (firstname!=null || lastname!=null)) { String contactName=null; if(firstname!=null && lastname!=null) contactName = firstname+" "+lastname; else if(lastname==null) contactName=firstname; else contactName=lastname; // go through all the phone numbers for (int i = 0; i < telCount; i++) { // check if it is a mobile phone and put it at the beginning // this doesn't necessary work since in many cases is up // to the user to indicate whether it is a mobile phone int telAttributes = contact.getAttributes(Contact.TEL, i); String telNumber = contact.getString(Contact.TEL, i); // check if ATTR_MOBILE is supported if (contactList.isSupportedAttribute(Contact.TEL, Contact.ATTR_MOBILE)) { if ((telAttributes & Contact.ATTR_MOBILE) != 0) { telNumbers.insertElementAt(telNumber, 0); } else { telNumbers.addElement(telNumber); } } else { telNumbers.addElement(telNumber); } allTelNumbers.addElement(telNumber); } // Shorten names which are too long if (contactName.length() > 20) { contactName = contactName.substring(0, 17) + "..."; } // insert elements in the list in order for (int i = 0; i < telNumbers.size(); i++) { append(contactName + ": " + telNumbers.elementAt(i), null); } telNumbers.removeAllElements(); } } available = true; } /*else { append("Contact list required items not supported", null); available = false; }*/ } finally { // always close it if (contactList != null) { contactList.close(); } } }
Create an inner
class for reading the contacts from the contacts list. The operation
is better handled in a separate thread so as to not lock the rest
of the MIDlet. When the contacts are read and printed on screen, add
a Command
for selecting a contact.
// load the names in a separate thread private class LoadContacts implements Operation { public void execute() { try { // go through all the lists String[] allContactLists = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST); if (allContactLists.length != 0) { for (int i = 0; i < allContactLists.length; i++) { loadNames(allContactLists[i]); } addCommand(selectCommand); } else { append("No Contact lists available", null); available = false; } } catch (PIMException e) { parent.showMessage(e.getMessage(), ContactListForm.this); available = false; append("Press a key to return", null); } catch (SecurityException e) { parent.showMessage(e.getMessage(), ContactListForm.this); available = false; append("Press a key to return", null); } } } }
Now that you have implemented the functionality for displaying the contacts list, handle incoming events.