Header Sep

Java Tips, Tricks & Code

Score
Login to rate page

May 2006

How to create a standby MIDlet for Java Platform 7 (JP-7) phones

With the new Sony Ericsson Java Platform 7 (JP-7) phones such as the K610, K800, K790 and W850, a new feature that lets the developer enable a MIDlet as a standby application is introduced. This functionality will be included in JP-7 phones after the initial market release. Just as the end-user can assign pictures and themes as wallpaper it is now also possible to select Java applications for this purpose. This standby MIDlet is handled by the application manager, and is started when the phone enters the standby mode. It is stopped when the user selects another wallpaper, theme or picture.

Download the source code here>>

Developing standby application MIDlets: considerations

There are two major issues that the developer must consider. The first issue is speed or more accurate screen frame rate. When the standby application starts, it runs in the background, and is assigned a low priority by the application manager. This means that the expected frame rate is considerably slower than for normal MIDlets, which means that for example 3D rendering is not well suited for standby MIDlets. Furthermore, the application needs to be quick off the mark. It has only 4-5 seconds to do something useful and show this to the user before the phone hibernates and enters energy saving mode.

The other issue is interaction. The application does not have focus when it runs in the background. This means that the end-user can't interface with the MIDlet during this state. The application can be activated however (see below), but this requires user interaction. Since the application can't receive end-user input while in the background, standby MIDlets that use restricted application programming interfaces should be signed to avoid user interaction while the MIDlet is running in the background. 

 
Fig 1: Standby MIDlet lifecycle as finite state machine.

Figure 1 shows the different states of a standby application. When the phone enters the Standby screen, the application is started (if not already running), and starts to execute in Inactive mode. The end-user can see what is drawn but cannot interact with the application. However, the application can be activated by Resuming it (just like resuming a minimized application). It then executes like an ordinary application. Minimizing the application makes it go back to Inactive mode again.

The application is terminated either by ending it when in active mode, or by setting another wallpaper.

Assigning an application as standby

Setting an application as wallpaper just involves a few basic steps.

1) Selecting Wallpaper from Display in the Settings menu.
2) Selecting Applications
3) Choosing one application from the list presented.   

You can also select an application as wallpaper application in the normal application list.

Fig 2: assigning a MIDlet as standby/wallpaper


Creating a standby MIDlet: the basics

First, to enable the MIDlet to run as a standby application we need to include and set a jad file property:
SEMC-StandbyApplication: <Y/N>

This sample application uses JSR 75 to load jpeg files from the camera album on the JP-7 phone. To check if the phone supports JSR 75 the following piece of code is useful:

try {
      Class tmp = Class.forName ("javax.microedition.io.file.FileConnection");
    } catch (Exception ex) {
      System.out.println (this.getClass ().getName () + ", Exception: " + ex.getMessage ());
      System.out.println ("No support for JSR-75");
      this.destroyApp (false);
    }

The camera album is located using the following paths.

private static String m_memoryStickPhotoPath = "file:///e:/DCIM/100MSDCF/";
private static String m_phoneMemoryPhotoPath = System.getProperty ("fileconn.dir.photos") + "100MSDCF/";

When the application is running on the emulator, the following path can be used to access a simulated filesystem.

private static String m_emulatorPhotoPath = "file:///root1/";


This path is actually pointing to the folder for the currently selected emulated device:
PC_Emulation\WTK2\appdb\SonyEricsson_W850_Emu\filesystem\root1

It is also possible to check if the application is running on the emulator using the following method:

public static boolean isEmulator () {
    return System.getProperty ("microedition.platform").endsWith ("JAVASDK");
  }


startApp, pauseApp, resumeApp and destroyApp

public void startApp () {
    System.out.println ("SlideShow.startApp: Start");
    if (!m_alreadyStarted) {
      this.initiate ();
      m_alreadyStarted = true;
    }
    startThreads();
  } public void pauseApp () {
    System.out.println ("SlideShow.pauseApp: Pause");
    if (!m_paused){
      m_paused = true;
      pauseThreads();
    } 
  }
public void resumeApp(){
    if (m_paused){
      m_paused = false;
      startThreads();
    }
  } public void destroyApp (boolean unconditional) {
    if (m_canvas != null)
      stopThreads();
  }

As for any MIDlet, it is important to manage resources in the startApp, pauseApp, resumeApp and destroyApp methods. A standby application needs to be quick off the mark as it has only 45 seconds to do something useful before the phone hibernates and enters energy saving mode. Basically, this means that the application should not waste time on reallocating resources.

The expected frame rate for an application running in standby is considerable slower than for normal MIDlets, which means that for example 3D rendering is not well suited for standby MIDlets.

Producer/Consumer

This standby MIDlet is good example of a producer/consumer problem. First the application needs to produce images, i.e. load and process jpeg files, then consume them and present the production result to the end-user, i.e. animate and display them on the screen. This can be solved by using two synchronized threads where the main animation thread waits for images to be produced by an image producer.

// PRODUCER
private void setFile () {
  synchronized (m_imageLock) {
    String fileName;
    while (imageLoaded){
      try {
        m_imageLock.wait ();
      } catch (InterruptedException e) {
                e.printStackTrace ();
      }
    } 
    imageLoaded = true;
    fileName = FileList.getNextFile ();
    loadImage (fileName);
    m_imageLock.notifyAll ();
  }
 }
 // PRODUCER
public Image getImage (){
    synchronized (m_imageLock) {
      if (m_paused) return backupPicture();
      while (!imageLoaded){
        try {
          m_imageLock.wait ();
        } catch (InterruptedException e) {
          e.printStackTrace ();
        }
      }
      imageLoaded = false;
      m_imageLock.notifyAll ();
      return m_image;
    }
  }

The consumer just calls the method getImage when we need to show the next photo. This method will either wait until another photo is ready or return the latest produced photo.

Standby and user-interaction

The application does not have focus when it runs in the background. This means that the user can't interface the MIDlet during this state. Added commands will not be visible until the application has focus. The application has focus when it is running as a normal MIDlet. The screenshots below illustrates the two different modes. The left screenshot shows the MIDlet running in the background with user-interaction disabled, and, consequently on the right we have the added commands About and Clear as soft keys.


public SlideCanvas (SlideShowMedia p_slidemidlet) {
    super();
    try {
     
      m_theMidlet = p_slidemidlet;
      SCREEN_HEIGHT = this.getHeight ();
      SCREEN_WIDTH = this.getWidth ();
     
      instructionCommand = new Command("About", Command.ITEM, 1);
      backCommand = new Command("Clear" , Command.BACK, 2);
     
      this.addCommand(instructionCommand);
      this.addCommand(backCommand);
     
      setCommandListener(this);  // make us listen
     
    } catch(Exception e) {
      e.printStackTrace ();
    }
  }

                
Standby vs activated.

Download example standby MIDlet source code and images>>

More information:

Score
Login to rate page