Push messages that automatically launch a Java mobile application

Add MIDP 2.0's push registry feature to your device application

Mobile technology continues to grow in popularity. And Java Micro Edition, or Java ME (Sun's new name for the J2ME platform), is one of the most prevalent technologies for developing mobile applications. Using Java ME, we can run many wireless applications in handheld devices that use either a JVM or KVM.

Included with Java ME is the Connected Limited Device Configuration (CLDC), which targets those devices that have limited resources and use a KVM. Also included in Java ME is the Mobile Information Device Profile (MIDP), a CLDC-based profile for running applications on cell phones. The application component, which runs in the mobile device, is a MIDlet, a MIDP application. A MIDlet is basically a set of classes designed to be run and controlled by the application management software (AMS) inside a mobile device.

The latest version of MIDP, 2.0, has introduced many new features for helping developers build robust enterprise applications, with one of the more important being the push registry. In Java ME applications, sometimes we need to push data from the server and launch a mobile application automatically in the device, without the device being explicitly started by the user. Imagine a situation where a user must be automatically notified when a work item has been created against his/her name and must respond to the work item as soon as possible. Java ME's push registry easily pushes a message to a Java ME application and automatically launches the application. In this article, I will show you how you can add the push registry feature to your mobile application.

The push registry's behavior can be described in the following three steps:

  1. The MIDlet registers a port along with the protocol name in the mobile device such that, if any message arrives in the specified port with the protocol mentioned, the AMS delivers it to the MIDlet. The registration is done statically using the Java ME application descriptor (JAD) file. The program can also perform dynamic registration using an API inside the application.
  2. From the server, a message is sent to the specific mobile device using the particular protocol and port where the MIDlet application is registered to listen.
  3. After the message is delivered to the mobile device, the AMS calls the MIDlet application, which has registered to listen to that particular port and particular protocol. Once the message is delivered to the MIDlet, it is the application's responsibility to process the message accordingly. Typically, an application may choose to open a screen, depending on the message, and allow the user to do some server transaction.

To push the message from the server, in this article's example, we will use a GSM (global system for mobile communication) modem. Figure 1 describes at a high level the exact scenario we will achieve in this article.

Figure 1. High-level scenario of SMS push to a mobile device from the server

Each push registration entry in the jad file contains the following information: MIDlet-Push-<n>: <ConnectionURL>, <MIDletClassName>, <AllowedSender>.

  • MIDlet-Push-<n>:: The push registration attribute name. Multiple push registrations can be provided in a MIDlet suite. The numeric value for <n> starts from 1 and must use consecutive ordinal numbers for additional entries. The first missing entry terminates the list. Any additional entries are ignored.
  • ConnectionURL: The connection string used in Connector.open().
  • MIDletClassName: The MIDlet responsible for the connection. The named MIDlet must be registered in the descriptor file or the jar file manifest with a MIDlet-<n> record.
  • AllowedSender: A designated filter that restricts which senders are valid for launching the requested MIDlet.

The MIDP 2.0 specification defines the syntax for datagram and socket inbound connections. When other specifications define push semantics for additional connection types, they must define the expected syntax for the filter field, as well as the expected format for the connection URL string.

A typical example of push registry in the jad file, using socket connection, resembles the following: MIDlet-Push-1: socket://:77, com.sample.SampleApplication, *. This sample descriptor file entry reserves a stream socket at port 77 and allows all senders.

Pushing the message from the server to the mobile device leads to some issues: If we want to send a message to a particular device that has registered to listen to the socket stream on a specific port, we must know the mobile phone's wireless network IP. As many phones do not use the always-connected environment in the wireless network (sometimes the provider does not support the device's static IP inside its network), sending a message to such a device is problematic. If we do not know the device's wireless IP, we will not be able to send a message to the device using the socket connection from the server.

Short message service (SMS) comes in handy for this situation. With SMS, we specify the destination device's phone number; so in this situation, we do not need to know the device's IP address. But using SMS as a trigger also involves some issues: Since the MIDP 2.0 specification defines the syntax for datagram and socket inbound connections and not for SMS connections, it is not guaranteed that all the devices supporting MIDP 2.0 will be able to use SMS as a trigger for the push registry. But the Wireless Messaging API (WMA 1.1)—an optional package over MIDP, which can support SMS—is now supported by many mobile devices, so there is a better chance that SMS will be supported by many devices as a trigger to the push registry. For this article, I use a Nokia 6600 mobile handset, which supports SMS as a push registry trigger.

In addition, sending an SMS message from the server to the device is not straightforward, since multiple approaches are available. SMS service providers provide the APIs (or expose service URLs) through which you can send messages to the designated mobile phone from your server-side application. But this approach requires a dependency on the SMS service provider and its special plans. The alternate way is to use a GSM modem, where you need to interface the GSM modem with your server-side application. In this article, I use an open source product, SMSLib for Java v1.0 (formerly jSMSEngine), which interfaces the GSM modem with the Java server-side application.

Another important point to note here is that a simple SMS message will not activate the MIDlet. We must send the SMS message to the particular port where the MIDlet is registered to listen. Hence, the software (or the SMS service provider) used to send the SMS message must be able to send it to a device's specific port. The SMSLib for Java v1.0 supports this functionality.

When we use the GSM modem approach, we must understand that the GSM modem will internally use the SIM (subscriber identify module) card to send the SMS message. This SIM card is tied to a mobile service provider. So each SMS message will cost the same as a message sent from a normal GSM mobile phone. On the contrary, sending bulk SMS messages via the provider's SMS gateway may prove more cost effective for an enterprise application (depending on the service plan). But if an application does not need to send many SMS messages to trigger the MIDlet, then a GSM modem approach may be cost effective and removes the special bulk SMS service dependency from the mobile service provider.

Though I suggest buying a separate GSM modem for the approach's production usage, testing the behavior does not call for buying one. Currently, many GSM mobile phone models come with a built-in GSM modem. One of these mobile models can be used as a GSM modem instead of a separate one. In this article, instead of a separate GSM modem, I use another Nokia 6600 mobile phone, as Nokia 6600 has a built-in GSM modem.

Let's now develop a sample application that will enable us, from a Java server-side application, to send an SMS message to a mobile phone's specific port and automatically launch a MIDlet in the mobile device.

Develop the client-side MIDlet using the push registry feature

To develop the client, we will use the Sun Java Wireless Toolkit (formerly known as J2ME Wireless Toolkit). I use version 2.2. This product is free and can be downloaded from Sun's Website. To install and run this toolkit you must have J2SE 1.4.2_02 or a more recent version installed in your machine.

I use Windows 2000 Professional as the operation system.

After installing Sun's toolkit follow the steps described below:

  1. Open the KToolbar from the Start menu: select Programs, then J2ME Wireless Toolkit 2.2, then KToolbar. An application window will open, shown in Figure 2.

    Figure 2. Open the KToolbar. Click on thumbnail to view full-sized image.
  2. Now click on the New Project icon in the window just opened. A pop-up window will open; there you can specify the project name and MIDlet class name. Type MySamplePushRegistryProject for the project name and com.sample.MySamplePushRegistry for the MIDlet class name.

    Figure 3. Create a new project
  3. After Step 2, another pop-up window will automatically appear, which will allow you to set other settings for the project. Make sure you are in the API Selection tab. In this tab, select JTWI from the target platform drop-down menu (if not already selected). Also make sure the CLDC 1.0 radio button is selected. Uncheck the Mobile Media API checkbox (as we are not going to use any API related to multimedia). Refer to Figure 4 for your reference.

    Figure 4. Set the API preference. Click on thumbnail to view full-sized image.
  4. Now go to the Push Registry tab. Click on the Add button. A pop-up window will appear. Type sms://:50001 in the Connection URL field, com.sample.MySamplePushRegistry in the Class field, and * in the Allowed Sender field. Refer to Figure 5 for your reference.

    Figure 5. Set the push registry property
  5. After Step 4, an entry will be added in the parent window, as shown in Figure 6.

    Figure 6. Set the push registry property (continued). Click on thumbnail to view full-sized image.
  6. Now go to the Permissions tab. Click on the Add button. Select the javax/microedition/io/Connector/sms from the permission tree and click OK. Repeat the same step to add the permissions javax/wireless/messaging/sms/receive and javax/microedition/io/PushRegistry.
  7. After Step 6, three permissions will be added in the application, as shown in Figure 7.

    Figure 7. Add the permissions. Click on thumbnail to view full-sized image.
  8. Now go to the User Defined tab. Here we add a user-defined variable, which will contain the SMS port. From our program, we refer to this user-defined variable to read the SMS port. In this tab, click on the Add button. A pop-up window opens. Type SMS-Port as the property name. Select OK. The original pop-up window appears. Type 50001 as the value of the SMS-Port key, as shown in Figure 8.

    Figure 8. Add the custom property SMS-Port. Click on thumbnail to view full-sized image.
  9. Now click on OK in the Settings window. This action will bring back the KToolbar.
  10. After Step 9, if you look into the jad file generated by the above steps, C:/WTK22/apps/MySamplePushRegistryProject/bin/MySamplePushRegistryProject.jad (assuming that the J2ME Wireless Toolkit 2.2 has been installed in the C:/WTK22 directory), you will find the entire configuration, which you set in the earlier steps. One of the important entries is the following: MIDlet-Push-1: sms://:50001, com.sample.MySamplePushRegistry, *. This entry ensures your application will listen on port 50001 for an SMS message.

Let's now look at the code for the MIDlet application. Here, I only provide a partial code snippet of the MIDlet. See Resources to download the whole codebase used in this application.

 

public class MySamplePushRegistry extends MIDlet implements CommandListener, Runnable, MessageListener { //.... public void startApp() { smsPort = getAppProperty("SMS-Port"); String smsConnection = "sms://:" + smsPort; if (smsconn == null) { try { smsconn = (MessageConnection) Connector.open(smsConnection);

smsconn.setMessageListener(this); } catch (IOException ioe) { ioe.printStackTrace(); } } display.setCurrent(resumeScreen); } public void notifyIncomingMessage(MessageConnection conn) { if (thread == null) { thread = new Thread(this); thread.start(); } } public void run() { try { msg = smsconn.receive(); if (msg != null) { if (msg instanceof TextMessage) {

content.setString(((TextMessage)msg).getPayloadText()); } display.setCurrent(content); } } catch (IOException e) { e.printStackTrace(); } } //other methods to follow }

1 2 3 Page
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more