by Brian Carr

Picture this

news
May 16, 20036 mins

View Web camera snapshots using a J2ME-capable phone

Mobile Information Device Profile (MIDP) provides a Java API for writing wireless applications that run in all mobile phones, two-way pagers, and PDAs that support MIDP. Another name for MIDP applications is MIDlets. Let’s first cover some basics about working with MIDlets and Java.

A MIDlet is a Java class that extends the javax.microedition.midlet.MIDlet abstract class. First, a MIDlet extending the MIDlet abstract class must implement the startApp(), pauseApp(), and destroyApp() methods. Since all MIDP implementations must support images stored in PNG format, I use that format in this article’s examples. If your Web cam does not support exporting files to PNG format, you’ll need to convert them with a batch program. One such freeware program is IrfanView.

All MIDP implementations must provide support for the HTTP protocol. It’s recommended to use HTTP, as this allows the application to be portable across all mobile information devices. The figure below shows an overview of Web cam-to-PDA connectivity.

Set up your environment

For a development environment on your client machine, you will need three pieces of software:

  1. The Java 2 Platform, Standard Edition (J2SE). Be sure to set your environment variable as specified by the installation instructions.
  2. The Java 2 Platform, Micro Edition (J2ME) Wireless Toolkit. This toolset provides developers with the emulation environment and documentation to develop Java technology applications targeted at Connected Limited Device Configuration (CLDC)/MIDP-compliant mobile phones and PDAs.
  3. Web cam with image capture software. I used an X10 Web cam with the associated XRay software. Installation and configuration instructions come with the software. The XRay software takes snapshots on a periodic basis; the timeframe is customizable.

You will also need a code editor. You can use Notepad (for those working in Windows) or something fancier like jEdit.

You have multiple options for your server software. You can either use the Java 2 Platform, Enterprise Edition (J2EE) or Apache Tomcat. You will want to use Tomcat to follow this article’s examples without modification. This article’s source code has its roots from the PhotoAlbum example installed as part of the J2ME Wireless Toolkit. I’ve modified the code to fit our application needs more accurately.

Jump into the code

When the sample application you’ve created starts on your phone, the list of possible cameras is read from the Java Application Descriptor (JAD) file by calling the setupImageList() function:

 for (int n = 1; n < 100; n++) {
   String nthImage = "PhotoImage-"+ n;
   String image = getAppProperty(nthImage);
   if (image == null || image.length() == 0)
       break;
       String nthTitle = "PhotoTitle-" + n;
       String title = getAppProperty(nthTitle);
       if (title == null || title.length() == 0)
             title = image;
             imageNames.addElement(image);
             imageList.append(title, null);
 }

JAD files enable the device to verify things like whether the jar file is too big for the device and whether a new version of the MIDlet suite is already installed on the device without actually downloading the jar file. JAD files also provide the ability to add more cameras to the application without changing the byte code.

The setupImageList() function runs through a loop to read all the possible cameras from the JAD file. This list is stored in the variable imageList.

After you choose a camera you want to view from the list, the thread starts. The run() method displays the progress form to inform the user that the image is downloading. The application displays an alert if an out-of-memory error occurs. If the image is not found, a message appears, and the menu displays again. The createImage() method creates an HTTP connection back to your Web server:

 c = (HttpConnection)Connector.open(name);

The application checks to make sure the image is a PNG. If it’s not, an error message displays:

 if (!type.equals("image/png")) {
   throw new IOException("Expecting a PNG image, but received " + type);
 }

The DataInputStream reads the image via the HTTP connection:

 is = c.openDataInputStream();
 byte[] data = new byte[len];
 is.readFully(data);
 return Image.createImage(data, 0, len);

The PhotoFrame class does a fair amount of work here. It generates your frame and draws the image to the display:

 this.images = images;
 if (images.size() > 0) {
   Image image = (Image)images.elementAt(0);
   imageWidth = image.getWidth();
   imageHeight = image.getHeight();
 } else {
   imageWidth = 0;
   imageHeight = 0;
 }
 index = 0;
 imageX = (getWidth() - imageWidth) / 2;
 imageY = (getHeight() - imageHeight) / 2;
 genFrame(style, imageX, imageY, imageWidth, imageHeight);
 .
 .
 .
 g.drawImage((Image)images.elementAt(index),
       imageX, imageY, Graphics.LEFT|Graphics.TOP);

More Web cams

This example has the ability to view snapshots from three distinct cameras. If you want to add more, just modify the getimage.jad file. The easiest way to do this is via the J2ME Wireless Toolkit:

  1. Start KToolbar
  2. Click on Settings
  3. Choose the User Defined tab
  4. Click Add and type in PhotoImage-3 for the property name
  5. For the value, type in the location where your image-capture software stores the snapshots
  6. Click Add and type in PhotoTitle-3 for the property name
  7. For the value, type in a distinct name that describes where the camera is located or the types of images it will take (e.g., Front Door for a camera that monitors your house’s front door)
  8. Click Run

Modify the JAD file to point to your image snapshots, rather than those used in this example. Just point to the path on your Web server where you capture your images (e.g., http://127.0.0.1:8080/imgBabysRoom.png).

Run the examples

Now we’re ready to run the examples. As specified above, you must first configure your client and server environment. With the client and server configured, download this article’s source code and place the source code into the J2ME Wireless Toolkit directory (C:WTK104appsgetimage). With your CLASSPATH set, ensure you have included the J2SE in your PATH (path=%path%;C:j2sdk1.4.0bin). Then follow these steps:

  1. Start Apache Tomcat
  2. Start KToolbar
  3. In KToolbar, click Open Project and choose the getimage project
  4. Change the Device to DefaultColorPhone for a better viewing experience
  5. Click Build
  6. Click Run and have fun

Run the examples on your device

After you have tested the application via the emulators available to you in the J2ME Wireless Toolkit and are happy with the results, you should deploy the application to your J2ME device. Since this is a network application, test it on a live wireless network to ensure that its performance is acceptable. Depending on the manufacturer of your device, you will need to follow different processes for application deployment. See Resources below for a MIDP deployment reference.

Brian Carr is a senior database administrator, Oracle Certified Professional, and developer at a manufacturing company in Akron, Ohio.