Sun Java Solaris Communities My SDN Account Join SDN
 
Article

An Overview of the PIM Optional Package

 


 

Most - if not all - handheld or wireless devices manufactured today have the ability to manage information of importance to the end user, whether it's a calendar of appointments, a file of contacts, or a list of things to do. This ability is referred to as personal information management, or PIM for short. The PIM data is stored persistently on the device, of course, and is normally accessed by the user via one or more special-purpose applications. Up until now, however, that data has not been made available to J2ME applications, because no configuration or profile defines the necessary programming interfaces. The new PIM Optional Package fills that hole.

The PIM Optional Package (PIMOP) is one of two optional packages defined by JSR 75 through the Java Community Process. The other, the File Connection Optional Package, is discussed in another tech tip. Because the PIMOP specification is still awaiting final approval and no reference implementation is yet available, the information presented here is still subject to change.

As an optional package, PIMOP is not a required programming interface for any J2ME profile or configuration. (For more details on how optional packages work, see the article "J2ME Optional Packages.") It can be supported on any J2ME platform, however, because it depends only on the core classes defined by the Connected Limited Device Configuration (CLDC), which are available in all J2ME profiles. If you write applications that depend on PIMOP, however, you'll need to make a runtime check to ensure that PIMOP itself is in fact available. The check is simple: if the system property microedition.pim.version is non-null, PIMOP is available. For example:

...
// Check that PIM Optional Package is available
String v = System.getProperty( "microedition.pim.version" );
if( v != null ){
    // PIMOP available
} else {
    // PIMOP not available
}
...

The value of the microedition.pim.version property is the PIMOP version number. For the first release this value is "1.0". Subsequent updates to PIMOP will increase this value accordingly.

Note that you cannot ensure PIMOP's availability just by including the PIMOP classes with your application, because PIMOP depends on device-specific code for accessing PIM data. If the device doesn't support PIMOP, your application must either exit gracefully, or avoid using any of the APIs specific to PIMOP.

At its heart, PIMOP is all about managing lists of PIM data. PIMOP defines three kinds of PIM data, referred to collectively as PIM lists. The first is a contact list, which stores contact information (names, addresses, phone numbers, and so on) for persons and organizations. The second is an event list, which stores event information (appointments, reminders, due dates, and so on) for the user. The third is the todo list, which stores tasks that the user needs to perform. Not every device supports all three kinds of PIM data, but at least one of them must be available if the vendor claims PIMOP support.

All classes and interfaces defined by PIMOP are in the new package javax.microedition.pim. You access PIM data using a singleton instance of the class javax.microedition.pim.PIM, accessed using the static getInstance() method:

...
import javax.microedition.pim.*;
PIM singleton = PIM.getInstance();
...

Once you have the singleton, call its openPIMList() method to access a PIM list. All PIM lists are represented by the PIMList class and its three subclasses: ContactList, EventList, and ToDoList. The first parameter to openPIMList() specifies the kind of PIM list you want returned and must be one of the values PIM.CONTACT_LIST, PIM.EVENT_LIST, or PIM.TODO_LIST. The second parameter specifies the modification mode, PIM.READ_ONLY, PIM.READ_WRITE, or PIM.WRITE_ONLY. There is an optional third parameter, the name of the desired PIM list. If the name is not specified, the method returns the default PIM list of the given type - the default list normally maps to the appropriate list used by built-in (possibly non-J2ME) PIM applications. To obtain the default contact list, use, for example:

...
PIM singleton = PIM.getInstance();
ContactList cl = null;

try {
    cl = (ContactList)singleton.openPIMList(PIM.CONTACT_LIST,
					    PIM.READ_ONLY );
    // use the contact list
}
catch( PIMException ){
    // no contact list available!
}
catch( SecurityException ){
    // the application is not allowed to access the list
}
...

If the desired list is not available, openPIMList() throws a PIMException. Note also that this method may throw a java.lang.SecurityException - the J2ME environment may place restrictions on which applications can read or write PIM data, using whatever security model it sees fit. A MIDP 2.0 environment, for example, might allow only trusted MIDlets to access the device's contact list.

A PIM list is a container for a number of PIM entries or items. All PIM items are represented by the PIMItem class and its subclasses, named appropriately enough Contact, Event, and ToDo. Use the items() method of any given list to obtain an enumeration of PIM items; for example:

...
import java.microedition.pim.*;
import java.util.*;

ContactList list = ... // a contact list

try {
    Enumeration enum = list.items();
    while( enum.hasMoreElements() ){
	Contact contact = (Contact) enum.nextElement();
	// do something with the contact
    }
}
catch( PIMException e ){
    // an error occurred
}
catch( SecurityException e ){
    // can't read this list
}
...

You can also enumerate items that match specific criteria or that belong in specific categories (groups of items). Other methods let you add or remove items from the list, and obtain information from the items' data fields.

The specific fields available in a PIM item will vary depending on the device and the type of list. The PIMOP specification defines standard fields for each kind of list item, for the most part a subset of the fields defined in the vCard and vCalendar specifications (Internet standards for exchanging contact and calendaring information). A particular implementation may support only some of these fields, so it's important to query the implementation to see whether a desired field is available, with a call to isSupportedField(). An UnsupportedFieldException is thrown whenever an application tries to operate on a field the implementation doesn't support.

The PIMOP specification also defines standard data types for the fields because some fields store strings, others store dates, and so on. The field's type determines which methods are used to manipulate its values. For example, the TEL field of a Contact (the contact's telephone number) is a string, obtained using getString():

...
Contact contact = ...;
String tel = contact.getString( Contact.TEL, 0 );
...

The BIRTHDAY field, however, is a long, obtained using getDate():

...
Contact contact = ...;
long bday = contact.getDate( Contact.BIRTHDAY, 0 );
...

Note that each field can store multiple values, much as a Vector does. The second parameter to methods like getString() is an index identifying which of the values you want.

We've only scratched the surface of what's available from PIMOP. Other features include the ability to import and export data in vCard and vCalendar formats and the ability to define non-standard fields. For full details, check out the Javadoc for the PIM APIs, available from the JSR 75 specification page.



Back To Top