Introduction to Java ME

Last week we considered the different mobile development technologies available. This week we will focus specifically on possibly the most widely used: Java ME or Java Micro Edition.

Background

What is Java ME?

Java ME is a cutdown version of the full Java programming language, cut down so that it will fit onto mobile devices with limited memory and processing power. The first thing to make clear is that there is not one single version of Java ME. There are two editions, with different target devices (ref: Sun):

The CLDC and CDC versions of Java ME have different capabilities. Because we are focusing on mobile development, we will be examining CLDC, rather than CDC.

Configurations and Profiles

A typical phone supporting Java ME would include not only the CLDC, which is referred to as a configuration, but also a profile, the most common of which is the Mobile Information Device Profile (MIDP). The difference between the two is as follows (ref: Sun):

The advantage of having both a configuration and a profile is that it allows mobile manufacturers to add different profiles (each profile might have different graphical capabilities for example) to the base configuration depending on the capabilities of the device. For example a basic phone could support CLDC 1.0 plus MIDP 1.0, while a more advanced phone with greater graphical capabilities could support CLDC 1.0 plus MIDP 2.0.

JSRs - Java Specification Requests

The combination of a configuration and a profile, such as CLDC and MIDP, provides the most commonly needed features in mobile development, such as a graphical user interface and date/time manipulation. However there are a series of add-ons which cover more specific requirements of mobile applications, such as 3D graphics, Bluetooth connectivity, or location based services (being able to find your position on the earth with GPS, as we talked about last week). Each add-on is referred to as a JSR or Java Specification Request, and each is numbered. Examples of JSRs include:

Different phones include support for different JSRs. For example, only phones which include JSR 172 are able to run Java code which parses XML.

Java bytecode

It is important to realise that the phones do not actually run Java programming code directly. Java programming code (of which you will see an example below) is compiled to a binary format called Java bytecode, which is more optimised to be run directly by the phone. Java capable phones include a so-called Java Virtual Machine, a piece of software which actually runs the bytecode. You can think of it as being a bit like a software version of a CPU, so you have a Java Virtual Machine running Java bytecode, rather than an Intel CPU running Intel machine code.

Developing for Java ME

OK, that's enough background, now we'll move on to how to actually develop a Java ME application. As mentioned last week, you need to download a development environment to your computer. The development environment includes a graphical representation of a phone, which you can use to test out your application. For Java ME, the environment to use is the Sun Wireless Toolkit or WTK. This is available here.

Developing a Java ME application using the WTK

Once you have downloaded and installed the WTK, run it. Select the "New Project" button and enter a name for the project. This will create a new project. Note that the WTK is not a full Integrated Development Environment: you need to write your source files in a text editor like Notepad; but it does allow you to compile and run your Java code.

Where is the project created?

A first Java ME application

Here is the Hello World for Java ME:

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class HelloWorld extends MIDlet 
{
    
    
    TextBox txtName;


    public HelloWorld()
    {
        txtName = new TextBox("Enter your name","",50,TextField.ANY);
    }

    public void startApp()
    {
        Display display = Display.getDisplay(this);
        display.setCurrent(txtName);
    }

    // Midlets must have this even if blank - code to handle 
    // pausing the application
    public void pauseApp()
    {
        
    }
    
    
    // Likewise midlets must have this even if blank - code to handle 
    // destroying the application
    public void destroyApp(boolean unconditional)
    {
    }
}

To explain this code:

Making the application do something

So how can we react to user input? The next example demonstrates this:

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class Ex2 extends MIDlet implements CommandListener
{
    TextBox name;


    Command ok, quit;

    public Ex2()
    {

        name = new TextBox("Name","",50,TextField.ANY);
        ok = new Command("OK", Command.OK, 0);
        quit = new Command("Quit", Command.EXIT, 0);


        name.addCommand(quit);
        name.addCommand(ok);

        name.setCommandListener(this);
    }

    public void startApp()
    {

        Display display = Display.getDisplay(this);
        display.setCurrent(name);

    }

    public void commandAction(Command c,Displayable s)
    {
        if(c.getCommandType() == Command.EXIT)
        {
            notifyDestroyed();
        }
        else if (c.getCommandType() == Command.OK)
        {
            Alert a = new Alert ("Hello!", 
                "Hello " + name.getString(), null, AlertType.INFO);
            a.setTimeout(2000);
            Display.getDisplay(this).setCurrent(a);
        }
    }

    // Midlets must have this even if blank - code to handle 
    // pausing the application
    public void pauseApp()
    {
        
    }
    
    
    // Likewise midlets must have this even if blank - code to handle 
    // destroying the application
    public void destroyApp(boolean unconditional)
    {
    }

}

To explain the new features of this code:

Exercise

Download the WTK (from here) and install it to your computer; the C: drive is probably best.

  1. Create a new application in the WTK. Write code to display a text box with a label of "Enter your password".
  2. Add OK and Quit commands to your application. If the user selects OK, display an alert box which reads "You entered the password " plus the password that the user entered.
  3. Try adding a Back command (a Command with a command type of Command.BACK) as well. What happens? Play around with the command priorities to see how the behaviour differs.
  4. Modify your commandAction() method so that if the user enters "Java123" for the password, an alert box reading "Correct password!" appears, while otherwise, an alert box reading "Wrong password!" appears. Use an if statement, similar to the if statement in JavaScript or PHP. You can test for a string being equal to something using equals(), e.g.:
    if (text.equals("hello"))
    {
        // do something
    }
    
  5. Advanced (for people comfortable with programming only!): Write an application which asks for and validates both a username and a password. The correct username and password should be "admin" and "Java123" respectively. You need to:
  6. Add a Back command to the Password TextBox. If the user selects the Back command while the password text box is being displayed, it should take them back to the username text box.