Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

JVM Languages

Getting Personal with J2ME's PIM API


Tom is a technical writer providing support for J2ME wireless technologies at KPI Consulting Inc. He can be contacted at [email protected].


Ever wonder why the PDA market isn't as large as that of desktop computers? The competition fits neatly into your hand—it's the mobile phone. Mobile phones can store contact information and an event calendar, just like a PDA. The mobile phone can also do the PDA one better in that when you glance at a contact name, with just the push of a button you can call that person. Or, it can automatically capture a new client's number if they call your mobile phone. Certainly PDAs can do things that mobile phones can't, and the PDA's UI is much easier to use. However, consider that Nokia alone sold its billionth mobile phone last September (with 2 billion mobile phone subscribers worldwide), compared to the tens of millions of PDAs sold, and you can grasp that the phone's limited address book/calendar capabilities are quite adequate for many people.

However, while this is a fine state for consumers, the situation drives Java 2 Mobile Edition (J2ME) programmers nuts. That's because J2ME, the Java platform tailored for portable devices such as mobile phones, doesn't allow access to the device's address book. If you wrote a killer app that leveraged this information, and could sell it into a market with, conservatively, tens of millions of customers...

Not surprisingly, as a mobile phone tech-support person I often get asked if J2ME can access a mobile phone's address book. Until recently, all I could do was explain that this missing capability was for the sake of security, which is not an idle concern when your mobile phone carries all sorts of personal data on it.

However, I've recently had to change my tune. That's because the Java Community Process (JCP), a consortium of companies that develops standards and new technologies for the Java platform, ratified the final version of Java Specification Request 75 (JSR 75). This specification defines two optional Java packages that implement highly desired PDA functions on the J2ME platform:

  • The JSR 75 Personal Information Management (PIM) package provides access to a mobile phone's address book and calendar.
  • The JSR 75 FileConnection (FC) package offers a unified interface to a mobile phone's filesystem, especially those on removable media.

These specifications are available on the JCP web site (http://www.jcp.org/en/jsr/detail?id=75). In this article, I focus only on the JSR 75 PIM API.

Because there's a lag anywhere from 6 months to 18 months between the final ratification of a JSR specification and when the API appears in shipping phones, JSR 75-capable phones have only recently appeared on the market. So, this is as good a time as any to delve into the details of the PIM API.

Overview of the PIM API

The PIM API provides a standard interface to the contact, event, and to-do information in a device's PIM database. Quite often it acts as the front end to the phone's native PIM database, although for other portable devices the database could be implemented in Java. Critically, the PIM API was designed to access databases external to the device as well as its internal one. The external PIM database might be stored on a removable memory card, or reside on a remote server in the corporation. If the device has more than one database (perhaps an internal one in non-volatile memory and the other on a removable card), the PIM implementation automatically uses the default database.

A major problem for any PIM interface is how to get data in/out of the database it manages. The PIM API supports the import/export of PIM information using "virtual cards" that comply with the standards-based vCard 2.1 and vCalendar 1.0 formats. A vCard carries address book data (contacts), while a vCalendar contains events and to-do data. These formats were developed by the Internet Mail Consortium for the exchange of contact and calendar data among computer systems (http://www.imc.org/pdi/pdiproddev.html). The PIM API only supports a subset of the data fields these formats describe. This restriction lets mobile phones interoperate with the largest number of disparate platforms.

Both vCard and vCalendar use clear-text encoding that permits data transfers between devices with 7-bit interfaces, limited bandwidth, and short line lengths—making them ideal for wireless communications. This encoding simplifies the design of the reader/writer programs that manage the data import/export operations. This in turn significantly reduces the processing overhead of both the reader/writer programs, so portable devices can implement them. Both of these formats support 8-bit data transfers.

The PIM API maintains several distinct objects called "lists":

  • The contact list manages names, addresses, and phone numbers, and serves as an address book.
  • The event list handles activities such as appointments, daily tasks, and reminders. These activities are dependent upon a time, date, or time interval (usually for a recurring task or reminder). The event list typically acts as a calendar.
  • The to-do list stores activities that a user needs to complete. Because to-dos often have a time dependency such as a deadline date, the to-do list is often considered an extension of the calendar, even though it is implemented as a separate object with its own fields and methods in the PIM API.

To understand how these lists interface with the native database, I briefly review the J2ME architecture.

Getting Outside of the Box

A J2ME platform consists of a configuration and a profile. A configuration specifies the basic hardware and software required to implement the Java platform on a device, while a profile describes the software required to implement the device's runtime environment and system services. Other profiles can specify additional hardware and their software support classes. For example, a profile might add support for Bluetooth hardware and the Object Exchange (OBEX) protocol to manage file transfers through this wireless interface. A J2ME device has only one configuration layered over the device's hardware and native OS, while multiple profiles can be layered atop of the configuration to add other capabilities.

For most portable devices, the J2ME platform uses the Connected Limited Device Configuration (CLDC). The connection is assumed to be low bandwidth and intermittent, making the configuration suitable for wireless devices. The most common profile present on mobile devices is the Mobile Information Device Profile (MIDP), which defines a runtime execution environment that provides event queues, a GUI, and additional security. Often you'll hear the term "MIDlet" used to describe Java applications written for this profile.

Optional packages extend the capabilities of the J2ME platform, such as support for wireless messaging and multimedia. JSR 75 is also an optional package. Many optional packages extend the capabilities of the MIDP, but JSR 75 extends the CLDC. MIDlets can still use these APIs, however.

The PIM API's capability has important security implications: Personal data that resides outside of the J2ME sandbox security model is no longer sacrosanct. Put another way, an application inside the sandbox can now access information outside of the sandbox, courtesy of the PIM API. To safeguard such data, the PIM API has a security mechanism that implements read-only, write-only, and read/write access controls for the data. In addition, a JSR 75 PIM implementation must respond to any SecurityExceptions its methods throw.

A mobile phone with a MIDP 2.0 profile can extend the PIM API's security with its trusted code mechanism. One aspect of this scheme is that only trusted code in the form of a digitally signed MIDlet can access any privileged (restricted) APIs. For security, phone vendors often implement the PIM API as a restricted API. As a result, a MIDlet has to be digitally signed by a trusted code authority before it is granted access to the PIM API. This reduces the potential for downloading a spyware MIDlet that reads your personal data and phones it home to a hacker. However, bear in mind that the trusted code security mechanism only safeguards access to the API, and not to the data. If a program glitch inadvertently corrupts the information within the native database, you're on your own. Therefore, the promise and peril of the PIM API is that while it grants access to the phone's personal data and so offers great potential for application developers, it also opens the door to great mischief.

PIM Classes and Interfaces

Given the wide diversity of the personal data it handles, the PIM API's object hierarchy is starkly simple. It has six classes, four of which handle exception conditions. The other two classes, PIM and RepeatRule, provide access to the native database or establish a recurring event, respectively. Figure 1 displays the API's class and interface hierarchy. The four exception-handling classes, FieldEmptyException, FieldFullException, PIMException, and UnSupportFieldException, are not shown in the figure. Table 1 lists these classes and interfaces and provides a summary of their purpose.

Another eight interfaces specify how to access PIM data. The PIM API maintains contact, event, and task information through appropriately named Contact, Event, and ToDo interfaces. Each interface contains items that represent various data entries in the database. You access the data within an item's object through the fields the interface provides. Each PIM item defines these fields according to their purpose, such as a NAME field for a contact's name. The PIMItem interface provides access to an item's data through getter/setter methods that manipulate standard Java data types.

PIMItem is the superclass for the Contact, Event, and ToDo interfaces. These interfaces inherit PIMItem's core methods, while extending them to handle the unique characteristics of their data. For example, the Event interface defines a pair of methods used to set or retrieve a RepeatRule object, and it has START and END fields that describe the Event's start and end times.

JSR 75 organizes related PIM items into lists, letting you manage and maintain the PIMItems populating the database. If you need to search through to-do information, then you access the ToDoList. The PIMList interface implements the core functions that create and delete PIMItems. This interface also has methods for organizing the data and examining some of its characteristics. A PIMList also dictates which fields it supports for data storage and retrieval. While a PIMItem specifies all of the possible fields supported by the vCard and vCalendar, it is the corresponding PIMList that determines which fields in the PIMItem the device's PIM implementation actually supports.

Similar to PIMItem, PIMList is the superclass for the ContactList, EventList, and ToDoList interfaces. Each of these interfaces provides specialized methods for importing, creating, and removing the PIMItems that they manage.

Using the PIM API

To make use of the PIM API, your MIDlet code first imports the javax.microedition.pim package. Because the JSR 75 PIM API is an optional package, it may not be present on the mobile phone. A prudent programmer should first discover if the package is present. This is done by invoking System.getProperty() with a query string of microedition.pim.version. If the package is present, the method returns a version number and you're set. If the query returns null, the package is absent and you should present a polite message stating such. One gotcha here is that the CLDC lets a J2ME device refuse to load applications that reference classes missing from its implementation. Because the PIM API is an optional extension to the CLDC, the device might not load the MIDlet, rather than give it a chance to run and check for the PIM API's presence.

Once you've confirmed that the PIM API is available, you obtain an instance of PIM to gain access to the phone's database. Quite often you'll combine this step with an operation that involves fetching a PIM list, as Listing One (available electronically; see "Resource Center," page 5) illustrates. Not only does the code get an instance of PIM, but also opens a ContactList with read and write access.

Now that you've connected to the database, you'll search it for any PIMLists it contains. The listPIMLists() method returns the names of all PIM lists of the specified type (say, EventList) in a String array. The first name in this array is the default list.

With the list names in hand, the next step is to open the desired list with the openPIMList() method. The constants PIM.CONTACT_LIST, PIM.EVENT_LIST, and PIM.TODO_LIST determine the type of list this method opens. Or, a list can be referenced by name. If a name isn't specified, openPIMList() opens the default list of the specified type. Listing Two (also available electronically) locates and opens the default PIMLists. The openPIMList() method is also where you set the list's access mode (read-only, write-only, or read/write). Because you're working with personal data, it goes without saying that you should code defensively and be prepared to catch any exceptions that occur.

We're almost ready to work with a particular PIMItem. However, while an item describes all of its fields from the vCard/vCalendar specifications, recall that the PIM API implementation supports only a subset of them. To confirm support for a particular field, you invoke PIMList's isSupportedField() method, which returns a Boolean value of true if the field is accessible. In addition, you can consult the device's technical documentation to verify which fields the PIM implementation supports. Usually, this information is buried in an appendix or implementation notes, but is well worth tracking down to confirm that the target phone permits access to the desired information.

If the requested field is available, use PIMList's items() method to fetch the list's items. Provide the field name to the PIMItem's countValue() method to obtain the number of data values stored in it. If countValue() returns nonzero, call the appropriate getter/setter methods to read and revise the values. Listing Three (available electronically) shows how to access all of the names in the default Contact list. As a safety feature, none of the changes you make propagate into the native database until you invoke the commit() method. The Sun Microsystems Wireless Toolkit (WTK) Version 2.2 provides an excellent demo MIDlet that uses the JSR 75 PIM API to access and update a mobile phone's database (http://java.sun.com/products/sjwtoolkit/download-2_2.html).

Last but not least, recall that the PIM API can import and export PIM data. The method fromSerialFormat() imports data for one or more PIMItems from an InputStream. The InputStream could be connected to another mobile device, or over the air to a corporate mainframe. The method toSerialFormat() writes one PIMItem to an OutputStream. Listing Four (also available electronically) shows how Contacts can be read from a resource containing vCards to populate a ContactList, and then commit the new information into the native database. I've written a simple demo MIDlet (also available electronically) that imports various PIM items and displays them.

Conclusion

The JSR 75 PIM API offers a standard way to access the database on many mobile phones. This capability lets J2ME developers enhance many existing applications. For example, a wireless messaging application that formerly had to maintain its own list of contacts and electronic addresses can now access the phone's native database for this information. This makes for a smaller (no separate contact list code required) and more robust application (the contact information comes from a reliable native database). In addition, the PIM API offers the means to develop a new breed of person-savvy applications. What might those be? Only time—and the ingenuity of J2ME programmers—will tell.

DDJ


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.