Mobile Phone Development

Colin P. Fahey


<<< BACK TO MOBILE DEVELOPMENT


SIMPLE J2ME APPLICATION

Using any text editor, you can type in code, like this "HelloMIDlet.java"
source file:


Here it is again, in plain text form so you can cut and paste: FILE: HelloMIDlet.java

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class HelloMIDlet extends MIDlet implements CommandListener { private Command exitCommand; private Display display; private TextBox t = null; public HelloMIDlet() { display = Display.getDisplay(this); exitCommand = new Command( "Exit", Command.EXIT, 2 ); t = new TextBox ( "Hello MIDlet", "Test string", 256, 0 ); t.addCommand(exitCommand); t.setCommandListener(this); } public void startApp() { display.setCurrent(t); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == exitCommand) { destroyApp(false); notifyDestroyed(); } } }

COMPILE *.JAVA TO *.CLASS:

cd c:\HelloMIDlet

************************************************ CAUTION: The following command must be on a single line, but has been expanded to several lines for clarity. ************************************************

[CURRENT DIRECTORY: "C:\HelloMIDlet"]

javac -target 1.1 -d .\ -bootclasspath c:\j2me\midp\classes HelloMIDlet.java


*************************************************************** NOTE: The "-target 1.1" is necessary to avoid an error in the future "preverify" stage. Apparently this has something to do with a problem with MIDP 1.0.3 support in JDK 1.4. ***************************************************************

PREVERIFY TO GENERATE NEW *.CLASS FILE:


[CURRENT DIRECTORY: "C:\HelloMIDlet"]

preverify -classpath c:\j2me\midp\classes;. HelloMIDlet

This generates a new *.class file in a new sub-directory called "output" (by default).

TEST OUT THE NEW *.CLASS FILE:


[CURRENT DIRECTORY: "C:\HelloMIDlet"]

midp -classpath c:\j2me\midp\classes;.\output HelloMIDlet

This looks to the new "output" directory for the necessary *.class file, and executes the application in a phone emulator. Here is what I saw:

CREATE A NEW TEXT FILE "manifest.mf" AND EDIT:

A manifest file is essential to getting an actual cell phone to comprehend your *.JAR file. If you do not have a proper manifest file included in your *.JAR file, then the phone will download your *.JAR file just fine, but will barf just before execution, saying: "Unsupported Content Type". Here is a manifest file that I created:
Here is that manifest file in plain text form, for convenient cut-and-paste use: FILE: manifest.mf

MIDlet-1: My_Description,, HelloMIDlet MIDlet-Name: My_Midlet_Suite MIDlet-Vendor: Colin Fahey, Inc. MIDlet-Version: 1.0 MicroEdition-Configuration: CLDC-1.0 MicroEdition-Profile: MIDP-1.0

Notice that the CLDC and MIDP versions are specified in this file. Be very conservative with the fields in this file. If you get "File Corrupt" errors, try eliminating all fields that I don't show above. Next, put the fields in the ORDER I show above. Next, shorten each field value as much as you can, and keep the characters limited to simple letters, digits, period, dash.

CAUTION: When you use the "jar" command to create a JAR file, and you specify the "manifest.mf" file, the jar utility reads in your manifest file AND ADDS NEW FIELDS when it creates the MANIFEST.MF file within the resulting JAR file! Do not extract a MANIFEST.MF file from a JAR file and attempt to form a new JAR file using that manifest file. If you extract this file, modify it by hand, eliminating any added fields.

NOTE: Icons for applications apparently do not show up on the Motorola T720 phone. This is why I did not describe my midlet with an icon, like this: MIDlet-1: My_Description, /icon.png, HelloMIDlet If you are developing for other phones that do display icons for applications, then you can give the icon filename, and add the icon image when you build your JAR file.

PUT THE MANIFEST AND THE *.CLASS FILE IN TO A *.JAR FILE:

The following command line creates a *.JAR file, inserting the manifest.mf file and the *.class file found in the specified path.
[CURRENT DIRECTORY: "C:\HelloMIDlet"]

jar cfm hi.jar manifest.mf -C .\output HelloMIDlet.class

Let's say you have an icon ("icon.png") that you want to mention in the *.JAD file as "/icon.png". (NOTE: Application icons don't show up on the T720, but do show up in the midp emulator and other phone models.) Let's say you have a sub-directory with image files (*.png format) called "images", and you want this directory to be accessible by your J2ME application as "/images", thus "a.png" is accessed by your J2ME application as "/images/a.png". Let's say all of your "preverify" output classes are in a sub-directory called "verified", including the main class of your application, "MyApp.class". All of these classes are to be accessed in the root directory of your *.JAR file. Here is a command line to form the JAR file: (NOTE: Command is expanded to several lines for clarity. You must type the command on a single line.) jar cfmv [Create JAR, Specify JAR Name, Add manifest.mf, Verbose] MyApp.jar [Name of output JAR file] manifest.mf [The manifest.mf file] icon.png [Optional icon, specified by JAD as "/icon.png"] images [Directory to add to JAR as "/images"] -C .\verified . The last line is especially tricky. It means: "Change local directory to .\verified, and then put all class files found in relative directory '.' (namely all class files in the new local directory) in to the JAR." Since you changed local directories before specifying the path of the classes to put in the JAR, the local path won't appear in the relative path when the files are placed in to the JAR file. Just to make this more explicit, if I have my preverified classes in: C:\MyApp\verified With classes like: C:\MyApp\verified\w.class Then doing "-C .\verified ." in the jar command line from the local directory "C:\MyApp" will result in "w.class" being placed in the root directory of the JAR file. WARNING: When you use the "-C" feature, it changes the local directory at that point of processing the command line arguments. Thus, the jar command may complain that it can't find your files past your first use of "-C" on the command line. You can use "-C .\verified ." at the end of your command line to keep things simple. Here is an example of the verbose output of the jar command line: added manifest adding: icon.png(in = 449) (out= 454)(deflated -1%) adding: images/(in = 0) (out= 0)(stored 0%) adding: images/a.png(in = 2463) (out= 2223)(deflated 9%) adding: images/b.png(in = 1322) (out= 579)(deflated 56%) adding: images/c.png(in = 3433) (out= 2874)(deflated 16%) adding: images/d.png(in = 1524) (out= 801)(deflated 47%) adding: w.class(in = 2570) (out= 1356)(deflated 47%) adding: MyApplication.class(in = 4714) (out= 2169)(deflated 53%) adding: x.class(in = 3239) (out= 1429)(deflated 55%) adding: y.class(in = 14205) (out= 6481)(deflated 54%) adding: z.class(in = 9448) (out= 5135)(deflated 45%)

CREATE AND EDIT A NEW *.JAD FILE:

A *.JAD file is necessary so that the cell phone can describe your application to the user before downloading. The *.JAD file also provides some indirection from the *.JAR itself, if that's any use to you.
FIGURE: An example *.JAD file describing a *.JAR file. Here is the example *.JAD file in plain text form so that you can cut-and-paste the body: FILE: hi.jad

MIDlet-1: My_Description,, HelloMIDlet MIDlet-Jar-Size: 1283 MIDlet-Jar-URL: http://www.colinfahey.com/hi.jar MIDlet-Name: My_Midlet_Suite MIDlet-Vendor: Colin Fahey, Inc. MIDlet-Version: 1.0

There are tools to generate this *.JAD, which make it easier to update the "MIDlet-Jar-Size:" field every time you rebuild the *.JAR file. Search the net for J2ME tools. NOTE: If the size field doesn't give the exact byte count for the *.JAR file, you will get the following error after a successful download and install to your phone: "Download Failed" NOTE: I think the following error indicates bad fields in the *.JAD, or bad fields in the manifest.mf file embedded in the *.JAR file: "Failed: File Corrupt"

NOTE: Although some web servers (Apache) seem to work fine with local JAR files (in the same directory as the JAD), as in: MIDlet-Jar-URL: hi.jar It appears that other servers (e.g., Yahoo!) require the full path, as in: MIDlet-Jar-URL: http://www.colinfahey.com/hi.jar But this is just the beginning of problems between the T720 and Yahoo! web servers. In any case, putting an explicit URL is generally safer.

TEST THE *.JAR AND *.JAD FILES BY EXECUTING:

The following executes the class found in the *.JAR file, described by the *.JAD file.
[CURRENT DIRECTORY: "C:\HelloMIDlet"]

midp -classpath c:\j2me\midp\classes;.\hi.jar -descriptor hi.jad

REFERENCES FOR J2ME, MIDP, CLDC DEVELOPMENT:

Much of what I presented here can be found on many other sites. However, I corrected some errors, filled in missing details, and generally made an effort to present the complete experience of someone trying to do this stuff. Here are very informative links that helped me get started: http://wireless.java.sun.com/midp/articles/getstart http://wireless.java.sun.com/midp/articles/setup


<<< BACK TO MOBILE DEVELOPMENT



CONTACT INFORMATION

Colin P. Fahey cpfahey@earthlink.net

http://www.colinfahey.com