Chapter 22. iAppli: Micro Java with a Twist

In Chapter 6 we looked at i-mode, NTT DoCoMo's popular wireless network. Just as WAP is too limited for true interactive applications, i-mode is too simplistic for apps such as games that require quick reactions, decent graphics and animations, always-connected networking, and sounds.

Like many other mobile phone manufacturers, NTT DoCoMo decided that Java was the answer. However, at the time of this decision, the MIDP specification was just beginning to be fleshed out and taken seriously. NTT DoCoMo, unfortunately, didn't have time to wait. They also wanted to create a library specially geared toward their particular service, brand, and mobile phone constraints.

So NTT DoCoMo built atop the CLDC basics and came out with their own Micro Java profile. It has lots in common with MIDP, but branches off in some interesting and weird directions.

Instead of MIDLets, NTT DoCoMo's Java apps are known as iApplis. The first Java handsets went on sale in Japan in January 2001. A full list of current phones capable of running iApplis can be found in Chapter 2, “The Mobile World.”

NOTE

While reading about iApplis on the Web, you might come across the word keitai. This is a Japanese word meaning “portable,” and is often used in the vernacular to refer to mobile phones (keitai denwa).

The Architecture of It All

iAppli applications can run on any 50x series of i-mode phone. The extensions library basically sits atop the CLDC class library. Like MIDP, iApplis are based on a subset of the java.lang, java.io, java.util, and javax.microedition.io classes.

iApplis are defined using five special packages: com.nttdocmo.io, com.nttdocmo.util, com.nttdocomo.ui, com.nttdocomo.net, and javax.microedition.io.

In addition, like MIDP, the i-mode library runs using the KVM. Additionally, various phone manufacturers might add additional functionality and handset-specific libraries.

The architecture looks something like Figure 22.1.

The iAppli architecture.

Figure 22.1. The iAppli architecture.

Basically, the i-mode extension library handles the following:

  • User Interface—Graphics and clear interface widgets are a major focus for NTT DoCoMo. For example, iAppli supports i-melody sounds and i-anime animated images.

  • Networking—All communication occurs using HTTP. Fully functional client-server application can be run, allowing for true multiplayer gaming or games that change over time based on input from a central server.

  • Scratchpad—Applications or data downloaded from the networks can be stored on the mobile phone. This allows for permanent storage of a user's most useful applications. Scratchpad is the storage memory where “files” can be saved and loaded.

  • Text Conversion—iAppli handles all Japanese language processing. Just like i-mode's browser, iAppli deals with the Shift JIS (SJIS) Japanese character encoding. Java applications can also display the emoji picture symbols used throughout i-mode.

In addition to providing room for the iAppli classes, media, and ScratchPad, each handset has a Java Application Manager (JAM) that controls the activation of applications in i-mode phone terminals.

Provisioning

The iAppli architecture makes deploying Java applications really easy. You just drop the application on a Web server. The program is downloaded using HTTP, the same way i-mode formatted cHTML documents are downloaded.

All Java classes, multimedia files, and other data files are packaged in a JAR file and can be downloaded all at once. Alternatively, individual images, sounds, or other pieces of data can be downloaded on-the-fly by the Java application during runtime.

NOTE

An iAppli program, packaged in a JAR file, can only take up a maximum of 10KB. The phone terminal allocates at least 5KB of room for a ScratchPad. Most Java-enabled i-mode phones will hold at least three JAR files and ScratchPads.

Additionally, each iAppli package must include an Application Descriptor File (ADF) with the extension JAM. This is a simple text file, much like a MIDPJAD file, that includes information about how to install, activate, and control applications. It also defines the application's size, its home URL, the size of the ScratchPad needed, and any specific start-up parameters. This can help a handset determine whether the iAppli program will run properly or fit in the available memory.

The ADF File

Some of the major parameters within the ADF file are detailed in Table 22.1.

Table 22.1. JAM File Properties and Parameters

AppName (required) Application name. This can be a maximum of 16 bytes long. This is the name that appears on the phone's application menu.
AppVer The current version number of the application.
PackageURL (required) The URL from which the JAR file can be downloaded.
AppSize (required) The size of the JAR file. Must be 10240 bytes (10KB) or less.
AppClass (required) The main class name, used to start the application.
AppParam Starting parameters for the main class. An application can call the getArgs() method to access this.
KvmVer Version of KVM, in case you are using a special version.
SPsize Size of ScratchPad needed for this application.
LastModified (required)

Last date and time the application was modified. Enables the phone to update the application when necessary. The format is: Dow, DD Mon YYYY HH:MM:SS

(Day of the week, Day, Month, Year, Hours, Minutes, Seconds)

UseNetwork You must set this to http when network communication is used.
TargetDevice The brand or version of mobile phone that this application will work on.
LaunchAt iAppli programs can be set to start up every time the phone is turned on, or at specific times, enabling users to set up personal agents that can download news, stocks, weather, gameworld status, or other info according to a regular schedule.

For example, a sample JAM file named MySample.jam might look like this:

AppName = MYSampleApp
AppClass = MySample
AppVer = 1.0
PackageURL = http://www.sample.com/MySample.jar
AppSize = 1014
AppParam = argl arg2 arg3
LastModified = Fri, 3 Mar 2002 11:11:11

The Provisioning Process

The provisioning process works as follows:

  1. A player reaches a content provider's Web page using the standard i-mode browser. A list of various Java games can be presented here. This page is created using cHTML.

  2. The player selects the game she wants to play. A message pops up warning the user that the game needs to be downloaded.

  3. The JAM file is downloaded. The phone then scans the file and determines whether the application will work on the particular model of handset. For example, if the application uses an extension library that only works on Sony phones and the player is using a Panasonic phone, then a message will be shown telling the player that the application cannot be installed.

  4. Likewise, she will be told if there's not enough room on the user's handset. She will usually be given the option to erase other Java applications and free up more memory.

  5. If the classes for the game already exist, then the JAR file will only be downloaded if the existing files are out of date.

  6. Downloading of the JAR begins. When the download is finished, the player gets a message stating that the application is now stored on the handset. The JAM now has a new applet in its menagerie.

  7. The player can now browse her local library of Java applications and select the game. She's off and playing!

All iAppli applications can also operate as standalone apps. For example, a user can enjoy a single-player action game without connecting to the network and incurring network fees of any kind.

Updating Applications

After an iAppli program has been downloaded, users can activate it directly from the original cHTML i-mode page.

Each JAM file has a LastModified entry. If the key is out of date, then the new JAR file will be downloaded and installed. After everything is installed properly, the old JAR file will be deleted. All data in the ScratchPad, however, will remain intact.

i-mode Extension Tags

To drop an iAppli program within an i-mode cHTML page, you can use the <OBJECT> tag as follows:

<OBJECT declare id="application.declaration" data="MySampleApp.jam" type="application/x-jam">
Here's a Sample IAppli Java Application
</OBJECT>

Point to the JAM file using the data attribute. You can then have the user download the iAppli as follows:

<A ijam="#application.declaration" href="fail.html">Download The Sample App!</A>

Note that the href attribute points to a URL that will only come up if the application's download fails. This is a good place to put an error or help page.

Priorities, Priorities

i-mode handsets will give priority to voice phone calls. When a call is received, the iAppli will be paused while the call takes place. When the player hangs up, the iAppli will be resumed.

If e-mail is received, the user will be alerted, but the iAppli will not be interrupted.

WARNING

If the iAppli is currently sending or receiving data over the network, then some phones will interrupt the data transfer, only to resume it later. Other phone models will simply restart the application. The user will usually have the option to turn this automatic switching on or off.

As such, every iAppli should implement the resume() method. This method can check to be sure no important data transfers were lost.

iAppli: Like MIDP, But Not Quite

All iAppli programs run from one main class, which must be derived from the com.nttdocomo.ui.IApplication class. When the application starts up, the start() method of this main class is run.

The most basic iAppli program would look like this:

import com.nttdocomo.ui.IApplication

public class Sample extend IApplication
{
    public IApplication(){
    }
 
    public void start(){
    }
}

When the application is finished, you need to call the terminate() method within com.nettdocomo.ui.IApplication. The System.exit() routine used with standard Java will not adequately shut the program down and clean up all the resources, and will likely throw a security exception.

Other methods within the IApplication superclass are the following:

  • String[] GetArgs()

  • IApplication GetCurrentApp()

  • String GetSourceUrl()

  • void resume()

  • abstract void start()

  • void terminate()

User Interface

Much as with MIDP, iAppli programs enable you to use either a low-level user interface API—drawing pixels directly on the screen—or writing to a high-level API, creating forms using buttons, list boxes, text fields, and other widgets.

All user interface output happens via the com.nttdocomo.ui.Display class. Major methods include the following:

  • int getHeight()—. Get the height of the current screen.

  • int getWidth()—. Obtain the width of the current screen.

  • void setCurrent(Frame frame)—. Set the current frame to be shown on screen. This can this a low-level Canvas or a high-level Form.

Low-Level UI

Low-level API is based on the com.nttdocomo.ui.Canvas class. Methods in this class include the following:

  • Graphics GetGraphics()

  • int GetKeypadState()

  • abstract void paint(Graphics g)

  • void processEvent(int type, int param)

  • void repaint()

  • void repaint(int x, int y, int width, int height)

A low-level implementation of iAppli Canvas is almost identical to the way you would do it with the MIDP standard. Basically, all the action happens in the paint() method.

You could create a simple Canvas class as follows:

import com.nttdocomo.ui.*;

public class MyCanvas extends Canvas(){

    MyCanvas(){
    }

    public void paint(Graphics g){
        g.lock();
        g.clearRect(0, 0, 200, 200);
        g.drawString("Hello", 10, 10);
        g.drawRect(5,5, 195, 195);
        g.unlock(true);
    }
}

Note the g.lock() and g.unlock() methods. You should always surround all drawing routines with these functions to draw to an offscreen buffer and create flicker-free graphics.

You could bring the canvas to life by creating an iAppli as follows:

import com.nttdocomo.ui.IApplication;

public class HelloIAppli extends IApplication{
    public void start() {
        MyCanvas myCanvas = new MyCanvas();
              Display.setCurrent(myCanvas);
    }
}

Graphics

The com.nttdocomo.ui.Graphics class is very similar to the MIDP's Graphics class. There are some interesting additions and omissions, however:

  • drawPolyline(int[] xPoints, int[] yPoints, int numPoints)—. Draws a continuous line segment between various sets of points.

  • fillPolygon(int[] xPoints, int[] yPoints, int numPoints)—. Paints a filled polygon with vertices indicated by xPoints and yPoints arrays. There is no corresponding function in the MIDP spec. However, MIDLets do enable you to draw arcs.

  • lock()—. Begins double buffering.

  • setOrigin(int x, int y)—. Sets the origin upon which all coordinates will be based.

  • setColor(int color)—. Sets a color to be used for drawing. Note that you must grab the appropriate color for the given handset using either the getColorOfName(int color) method or getColorOfRGB(int r,int g,int b). For example

    g.setColor((g.getColorOfName(g.YELLOW)))
    

    or

    g.setColor((g.getColorOfRGB(128,128,128)))
    
  • unlock(boolean forced)—. Ends double buffering. When you lock the graphics context, all drawing occurs in an offscreen buffer. When you unlock the buffer, the entire offscreen image is drawn to the actual screen. If you set unlock()'s forced parameter to true, then the drawing occurs immediately. Otherwise, the graphics are put in a queue and drawn as soon as possible.

High-Level UI

All high-level UI is achieved by creating a Panel. First off, you can set the title of the panel as follows:

setTitle("My Panel");

You can then add various user interface elements. Elements will appear in the panel according to the order you add them. You can adjust elements using standard component methods such as setEnabled(), setVisible(), and so on.

Some of the user interface elements are discussed in the following sections.

Label

You can create a text label, choosing the text you want to display and the justification. For example

Label lab = new Label("Username:", Label.LEFT);
add(lab);

TextBox

You can create a text input box using the TextBox(String text,int columns,int rows,int mode) method.

For example, to create two fields—one for a username (with a default name of "Henry") and one for a password, you would use:

TextBox name = new TextBox("Henry", 50, 1, TextBox.DISPLAY_ANY);
TextBox pass = new TextBox(null, 50, 1, TextBox.DISPLAY_PASSWORD);
name.setInputMode(TextBox.KANA);
pass.setInputMode(TextBox.NUMBER);

ListBox

The ListBox element is a powerful widget that enables you to create various types of selection menus. Types include the following:

  • SINGLE_SELECT—. A simple list of choices. The user may select one and only one option.

  • RADIO_BUTTONA list of choices, where each choice is preceded by a small button. The user may select one and only one option. This is shown in Figure 22.2.

    A check box version of ListBox.—

    Figure 22.2. A check box version of ListBox.—

  • NUMBERED_LIST—. A list of choices, each choice preceded by a number, starting from 1.

  • CHOICE—. A standard options menu choice list.

  • MULTIPLE_SELECT—. The user may select numerous items. Clicking on a item once selects it, clicking again deselects it.

  • CHECK_BOX—. A list of choices, each preceded by a check box graphic. The user may select numerous items. When an item is selected, its check box will be filled in (see Figure 22.2).

For example

ListBox lb = new ListBox(ListBox.RADIO_BUTTON);
String items[] = new String[3];
items[0] = "Choice 1";
items[1] = "Choice 2";
items[2] = "Choice 3";
lb.setItems(items);
add(lb);

Ticker

This enables you to create a scrolling text ticker, similar to the news tickertape in Times Square. The ticker will usually appear at the very top (or bottom) of the screen.

To create the ticker you could use code similar to the following:

Ticker tick = new Ticker();
tick.setBackground(Graphics.getColorOfName(Graphics.LIME));
tick.setText("This text will scroll and scroll forever!");
add(tick);

VisualPresenter

The VisualPresenter component enables you to create a scrollable area in which you can plop an image. You can then set various attributes such as IMAGE_XPOS and IMAGE_YPOS, which indicate where in the VisualPresenter the top right corner of the image will be drawn.

For example

VisualPresenter vp = new VisualPresenter();
add(vp);
vp.setAttribute(VisualPresenter.IMAGE_XPOS, 0);
vp.setAttribute(VisualPresenter.IMAGE_YPOS, 0);
MediaImage mediaImage = MediaManager.getImage("resource:///myimage.gif");
try {
 mediaImage.use();
}  catch (Exception e) {  }
Image img = mediaImage.getImage();
int imgWidth = img.getWidth();
int imgHeight = img.getHeight();
vp.setImage(mediaImage);
vp.setSize(Display.getWidth()/2, Display.getHeight()/2); 
vp.play();

Button

Buttons can be created and added very simply:

Button but = new Button("Hit Me!");
add(but);

You can detect whether the button is hit using a component event listener, which we will discuss in a later section.

Dialog Boxes

To create a dialog box, simply designate the type of dialog you want and the dialog box's title. Valid types include the following:

  • DIALOG_INFORMATION

  • DIALOG_WARNING

  • DIALOG_ERROR

  • DIALOG_YESNO

  • DIALOG_YESNOCANCEL

You can then add text to the dialog box and detect button presses. The buttons that appear will depend on the type of dialog you use. Various button types that are in the Dialog class include BUTTON_OK, BUTTON_CANCEL, BUTTON_YES, and BUTTON_NO.

For example:

Dialog dialog = new Dialog(DIALOG_INFORMATION,"Hello");
dialog.setText("Hello sir.");
dialog.show();

Handling Events

The event model for iAppli programs is similar to the listener-delegation model used in JDK 1.1.

If you are drawing a bunch of widgets using high-level user interface classes, listeners might not be registered within a component—but only in the container or panel that holds the component.

If you are drawing directly to the screen using the low-level APIs, all events are automatically passed to the processEvent() method of the Canvas drawing area. This method can be overridden and all events can thus be handled. You do not need to add a special listener.

Process Event on Canvas

The Canvas has its own event listener built in. Just use the processEvent(int type, int param) method.

There are two types of events:

  • KEY_PRESSED_EVENT—. A key was pushed.

  • KEY_RELEASED_EVENT—. The key was released.

Various keys can also be sniffed:

  • KEY_0 KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9—,. One of the numerical keys.

  • KEY_ASTERISK KEY_POUND—,. The asterisk (star) or pound (hash) key.

  • KEY_LEFT KEY_UP, KEY_RIGHT, KEY_DOWN—,. One of the cursor arrow keys.

  • KEY_SELECT—. The center select key.

  • KEY_SOFT1 KEY_SOFT2—,. One of the soft keys, usually at the top of the keypad.

You could create a Canvas that deals with keypad presses and other events as follows:

class HelloCanvas extends Canvas {

    // Put all drawing here, in the paint() method...

    public void processEvent(int type, int param)
        {
        if(type == Display.KEY_PRESSED_EVENT)
              {
                      int key = getKeypadState();
                      if (param == Display.KEY_RIGHT)
                          // The right cursor key was pressed.
            else if(param == Display.KEY_SOFT1)
                // Softkey 1 was pressed.
            else if(param == Display.KEY_SOFT2)
                // Softkey 2 was pressed.
            else if
        }
    }
}

KeyListener on a Panel

Panels, meanwhile, can implement various listeners. For instance, to detect key presses simply have your panel implement KeyListener. You can then set the panel as the listener within the constructor:

setKeyListener(this);

The panel must then handle two methods:

  • keyPressed(Panel panel,int key)

  • keyReleased(Panel panel,int key)

This enables the panel to detect any keypress, similar to the processEvent() method of Canvas.

Component Listener

Additionally, a panel can implement ComponentListener. This lets the panel deal with any changes to any of its components. For example, to deal with a button

public class ButtonTest extends Panel implements ComponentListener
{
 Button btn;

 ButtonTest() {
 btn = new Button("Button");
 this.add(btn);
 setComponentListener(this);

 public void componentAction(Component source, int type, int param)
 {
    if (source instanceof Button && type == BUTTON_PRESSED)
        // Do something!
 }
}

SoftKeyListener

Your panel or Canvas can also implement the SoftKeyListener class to deal directly with the two soft keys. Simply add a listener to your panel or Canvas's constructor method:

setSoftKeyListener(this);

Then set the label you want to appear on the phone's menu. This label is usually placed directly above the soft key:

setSoftLabel(Frame.SOFT_KEY_1, "Exit");

You can now implement SoftKeyListener using the softKeyPressed() and softKeyReleased() methods. For example

public void softKeyPressed(int key)
{
    if (key == Frame.SOFT_KEY_1)
        MainApp.terminate();
}

public void softKeyReleased(int key) {}

Graphics and Sound

iAppli can handle the following formats:

  • Still images—GIF 87 and 87a. Unlike MIDP, iApplis support transparent images. This is good news for game programmers!

  • Animations—GIF89a animated GIF sequences.

  • Sounds—i-Melody file (MLD) format. This is a format similar to MIDI, allowing up to 16 different voices. Most MLD files are less than 1KB in size.

    You can create i-Melody files using various tools. One popular tool is MLD Creator by Naka-Net (http://www.naka-net.com/SOFT/MLDC/).

Images and sounds can be loaded using the com.nttdocomo.ui.MediaManager's methods:

  • MediaData getData(String location)

  • MediaImage getImage(String location)

  • MediaSound getSound(String location)

There are two main locations you can read media from:

  • You can place images or sounds within the JAR that the iAppli Java classes are packaged in. In this case, you use the resource protocol:

    MediaImage mi = MediaManager.getImage ("resource: ///sample.gif");
    
  • You can grab a media file directly from a Web server using the HTTP or HTTPS protocol:

    MediaImage mi = MediaManager.getImage ("http: //www.sample.com/images/sample.gif");
    

    or

    MediaImage mi = MediaManager.getImage( getSourceURL() + "sample.gif" );
    

Displaying an Image

To display an image you could use code similar to the following:

MediaImage mi = MediaManager.getImage("resource:///sample.gif");

try{
 mi.use();
}
catch(ConnectionException ce){
    // Could not connect.
} catch(UIException ui){
          // Other exception.
}
Image img = mi.getImage();

You can now paint using a VisualPresenter component.

When you are temporarily done with the image, you can call unuse() to free up the memory. If you no longer need the image at all, you can call dispose() to unload the image entirely.

Playing Music

To play an audio file, use an AudioPresenter. The code is similar to the following:

AudioPresenter ap;
MediaSound ms;
ap = AudioPresenter.getAudioPresenter();
ms = MediaManager.getSound("resouce:///audio/test.mld");
try {
 ms.use();
}
catch (Exception e) {  }
ap.setSound(ms);

You can then play the sound at any time by calling

ap.play();

When finished, call the stop() method on your audio presenter and call unuse() and dispose() on your media sound object to dispose of the sound properly.

Listening to Your Music

You can also keep track of an audio clip by having your panel implement MediaListener. You can then set the listener as follows:

ap.setMediaListener(this);

Finally, you must implement the mediaAction method as follows:

public void mediaAction(MediaPresenter source, int type, int param)
{
 switch (type) {
 case AudioPresenter.AUDIO_PLAYING:
  break;
 case AudioPresenter.AUDIO_COMPLETE:
  break;
 case AudioPresenter.AUDIO_STOPPED:
  break;
}

Networking and Input/Output

There are basically two ways you can get and receive data:

  1. Through the network using HTTP or HTTPS communication. The iAppli inputs or outputs data using standard HTTP requests and responses. Java for i-mode applications cannot use non-HTTP(S) protocols such as TCP socket, UDP, and FTP.

  2. Read or write from a ScratchPad. Every iAppli is allotted 5KB of ScratchPad space.

HTTP Connections

In order to use HTTP communications, you have to add the "UseNetwork = http" line to your application's ADF (JAM) file.

Basically, HTTP communications work the same with iApplis as they do with MIDlets. For example, to read data from a servlet on the network (http://www.myhost.com/myservlet) and put it into a byte array called data you would use the following code:

HttpConnection http = null;
InputStream in = null;
byte[] data = null;
String URL = "http://www.myhost.com/myservlet";

try
{
 http = (HttpConnection)Connector.open(URL,Connector.READ);
 http.setRequestMethod(HttpConnection.GET);
 http.connect();

 int contentLength = (int)http.getLength();
 in = http.openInputStream();

 data = new byte[contentLength];
 in.read(data);
}
catch(ConnectionException ce)
{
 // Handle a connection exception.
}
catch(Exception e)
{
 // Handle other type of exception
}
finally
{
 try
 {
  if(in!=null)
  {
  in.close();
  in = null;
  }
  if(http!=null)
  {
  http.close();
  http = null;
  }
 }
 catch(Exception e)
 {
  http = null;
  in = null;
 }
}

To write to the server you would use code similar to the following:

http = (HttpConnection)Connector.open(URL, Connector.WRITE);
http.setRequestMethod(HttpConnection.POST);
http.setRequestProperty("Content-Type","application/octet-stream");
DataOutputStream stream = http.openDataOutputStream();
stream.write(data,0,data.length);
stream.close();
http.close();

CAUTION

For security reasons, iApplis can only access the Web site (the exact URL scheme, host name, and port number) from which they were downloaded. Also, be sure to use the host name when communicating with a server, not the IP address.

ScratchPad

Writing and reading to the ScratchPad is really easy. Simply use "scratchpad:///0" as the URL protocol. For example, to write four Unicode characters to the ScratchPad, use the following code:

try
{
 OutputStream out = Connector.openOutputStream("scratchpad:///0");
 out.write(0xfe);
 out.write(0xff);
 out.write(0x100);
 out.write(0x101);
 out.close();
}
catch (IOException e)
{
System.out.println("IOException in save");
}

And to read those bytes back in

try
{
 InputStream in= Connector.openInputStream("scratchpad:///0");
 for(int i=0; i<4; i++)
 {
  System.out.println(in.read());
 }
 in.close();
}
catch (IOException e)
{
 System.out.println("IOException in read");}
}

You could also read or write several bytes at a time using OutputStream's write(String data,int offset,int length) method. Then read in using the read(String data,int offset, int length) method.

Developing iApplis

Actually designing and creating iApplis is very similar to developing MIDlets. You need to have a Java compiler and JAR tool, which can be found in Sun Microsystem's J2SE toolkit.

My hope is that this chapter will get you off the ground and creating working iApplis. There is also lots of documentation on the Web, though much of it is in Japanese. The full iAppli specification and API can be found in Japanese at http://www.nttdocomo.co.jp/i/java/index.html. However, there is now an English version available at http://www.nttdocomo.co.jp/english/p_s/i/java/index.html.

If you happen to live in Japan and own an i-mode phone or two, then you're lucky—you can test your games out right on their target platforms. For those in the rest of the world, however, emulators will do the job nicely. Several emulators can be downloaded:

Most of the emulators are in Japanese, and will include lots of Japanese menus. If you explore, it should all make sense soon enough. In general, the first menu option on the phone is usually your test application. The second menu option usually allows you to quit. The i-JADE emulator, however, has an English version.

After you've got all the tools, follow these steps:

  1. Be sure to include Sun's cldc and NTT DoCoMo's com.nttdocomo libraries in your classpath, and compile your application. Most emulators have included the necessary classes as part of their own libraries.

    For example, to compile using the classes that come with the i-JADE emulator:

    c:jdk1.3injavac -classpath c:i-jadei-jade-p.jar MyApp.java
    

    Note that you might need to change the name of the JAR file from i-jade-p.jar, depending on the version of i-JADE you download. Different handset emulators have slightly different filenames.

  2. Test the application using an emulator. Run the emulator using:

    c:jdk1.3injava -jar c:i-jadei-jade-p.jar
    

    The emulator control panel appears, as seen in Figure 22.3. Here you can input either the name of a JAM file (which must point a JAR), or just a single Java class.

    Inputting a JAM file or Java class.

    Figure 22.3. Inputting a JAM file or Java class.

    If all goes well, you will then see your iAppli run in the emulator window, as in Figure 22.4.

    Emulating a Mine Sweeper game!

    Figure 22.4. Emulating a Mine Sweeper game!

  3. To actually deploy, you first need to pre-verify your classes. You can use the standard J2ME pre-verify technique discussed in Chapter 9, “First Steps.” The pre-verifier also comes with Sun's wireless toolkit:

    preverify -classpath c:cldcclasses;c:i-jadei-jade-p.jar;c: myclasses -d c:myOutput MyApp
    
  4. Create the JAM text file, such as myapp.jam.

  5. You now need to package your Java classes and all supporting media into a JAR file. Include all GIFs and audio files:

    c:jdk1.3injar cvf MyApp.jar MyApp.class image1.gif image2.gif
    
  6. Create a cHTML file with the <OBJECT> tag pointing to your JAR file.

  7. Put the cHTML file as well as the JAM text file on a public Web server.

You can now point your i-mode Java-enabled handset to the given Web address and download away!

After you've tested it and ensured that everything works, you can open your game to the public or strike a distribution and profit-sharing deal with NTT DoCoMo.

Summary

Because iApplis are so similar to MIDlets, it is usually feasible to write games for both systems. It should only take a few hours or days to port a well-written MIDlet so that it will run on NTT DoCoMo's i-mode system. Appendix D lists all the methods and classes that comprise the iAppli profile.

The next few chapters will go into other vendor-specific APIs that can help you write powerful games targeted at specific brands of mobile phones.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.226.4.191