Download as pdf or txt
Download as pdf or txt
You are on page 1of 30

CSE20 Mobile Application Development Unit III

J2ME OVERVIEW:

J2ME stands for Java 2, Micro Edition. It is a stripped-down version of Java targeted at devices which have
limited processing power and storage capabilities and intermittent or fairly low-bandwidth network connections.
These include mobile phones, pagers,wireless devices and set-top boxes among others.

A Sample Wireless Stack would consist of:

• Profiles
• Configurations
• Java Virtual Machines
• Host Operating System

What is a J2ME Configuration?


A configuration defines the minimum Java technology that an application developer can expect on a broad range
of implementing devices.
J2ME Connected, Limited Device Configuration (CLDC)

specifies the Java environment for mobile phone, pager and wireless devices
CLDC devices are usually wireless
160 - 512k of memory available for Java
typically has limited power or battery operated
network connectivity, often wireless, intermittent, low-bandwidth (9600bps or less)

J2ME Connected Device Configuration (CDC)

describes the Java environment for digital television set-top boxes, high end wireless devices and
automotive telematics systems.
device is powered by a 32-bit processor
2MB or more of total memory available for Java
network connectivity, often wireless, intermittent, low-bandwidth (9600bps or less)

These two configurations differ only in their respective memory and display capabilities.
What is a J2ME Profile?
A specification layer above the configuration which describes the Java configuration for a specific vertical market
or device type.
J2ME Profiles
J2ME Mobile Information Device Profile (MIDP)

this is the application environment for wireless devices based on the CLDC
contains classes for user interface, storage and networking

J2ME Foundation Profile, Personal Basis, Personal and RMI profiles

these are profiles for devices based on the CDC, which are not addressed in this tutorial

Virtual Machines
The CLDC and the CDC each require their own virtual machine because of their different memory and display
capabilities. The CLDC virtual machine is far smaller than that required by the CDC and supports less features.
The virtual machine for the CLDC is called the Kilo Virtual Machine (KVM) and the virtual machine for the
CDC is called the CVM.

J2ME Building Blocks: Configurations and Profiles :

While connected consumer devices such as cell phones, pagers, personal organizers and set-top boxes have
many things in common, they are also diverse in form, function and features. Information appliances tend to be
special-purpose, limited-function devices. To address this diversity, an essential requirement for J2ME is not
only small size but also modularity and customizability. The J2ME architecture is modular and scalable so that
it can support the kinds of flexible deployment demanded by the consumer and embedded markets. To enable
this, J2ME provides a range of virtual machine technologies, each optimized for the different processor types
and memory footprints commonly found in the consumer and embedded marketplace. For low-end, resource-
limited products, J2ME supports minimal configurations of the Java virtual machine and Java APIs that embody
just the essential capabilities of each kind of device. As device manufacturers develop new features in their
devices, or service providers develop new and exciting applications, these minimal configurations can be
expanded with additional APIs or with a richer complement of Java virtual machine features. To support this
kind of customizability and extensibility, two essential concepts are defined by J2ME:
• Configuration. A J2ME configuration defines a minimum platform for a “horizontal” category or
grouping of devices, each with similar requirements on total memory budget and processing power. A
configuration defines the Java language and virtual machine features and minimum class libraries that a
device manufacturer or a content provider can expect to be available on all devices of the same category.

• Profile. A J2ME profile is layered on top of (and thus extends) a configuration. A profile addresses the
specific demands of a certain “vertical” market segment or device family. The main goal of a profile is to
guarantee interoperability within a certain vertical device family or domain by defining a standard Java
platform for that market. Profiles typically include class libraries that are far more domain-specific than the
class libraries provided in a configuration. J2ME configurations and profiles are defined through the Java
Community Process (JCP).

J2ME Profiles:

Application portability is a key benefit of Java technology in the desktop and enterprise server markets.
Portability is also a critical element of the J2ME value proposition for consumer devices. In most cases
consumer devices have substantial differences in memory size, networking, and user interface capabilities,
making it very difficult to support all devices with just one solution. In general, the consumer device market is
not so homogeneous that end users expect or require universal application portability. Rather, in the consumer
space, applications should ideally be fully portable between devices of the same kind. For example, consider the
following types of consumer devices: – cellular telephones – washing machines – intercommunicating
electronic toys It seems clear that each of these represents a different “market segment” or “device family” or
“application domain.” As such, consumers would expect useful applications to be portable within a device
family.
• A profile provides a complete toolkit for implementing applications for a particular kind of device,
such as a pager, set-top box, cell phone, washing machine, or interactive electronic toy.

• A profile may also be created to support a significant, coherent group of applications that might be
hosted on several categories of devices. For example, while the differences between set-top boxes, pagers,
cell phones, and washing machines are significant enough to justify creating a separate profile for each, it
might be useful for certain kinds of personal information management or home banking applications to be
portable to each of these devices. This could be accomplished by creating a separate profile for these kinds
of applications and ensuring that this new profile can be easily and effectively supported on each of the
target devices along with its “normal” more device-specific profile. It is possible for a single device to
support several profiles. Some of these profiles will be very device-specific, while others will be more
application specific.
Applications are written “for” a specific profile and are required to use only the features defined by
that profile. Manufacturers choose which profile(s) to support on each of their devices, but are required to
implement all features of the chosen profile(s). The value proposition to the consumer is that any
application written for a particular profile will run on any device that supports that profile. In its simplest
terms, a profile is a contract between an application and a J2ME vertical market segment. All the devices in
the market segment agree to implement all the features defined in the profile. And the application agrees to
use only those features defined in the profile. Thus, portability is achieved between the applications and the
devices served by that profile. New devices can take advantage of a large and familiar application base.
Most importantly new, compelling applications (perhaps completely unforeseen by the original profile
designers) can be dynamically downloaded to existing devices.
At the implementation level, a profile is defined simply as a collection of Java APIs and class
libraries that reside on top of a specified configuration and that provide the additional domain-
specific capabilities for devices in a specific market segment.

J2ME Configurations:
In J2ME, an application is written “for” a particular profile, and a profile is “based upon” or “extends” a
particular configuration. Thus, all of the features of a configuration are automatically included in the profile and
may be used by applications written for that profile.

A configuration defines a Java platform for a “horizontal” category or grouping of devices with similar
requirements on total memory budget and other hardware capabilities. More specifically, a configuration:
• specifies the Java programming language features supported,
• specifies the Java virtual machine features supported,
• specifies the basic Java libraries and APIs supported.

J2ME is designed so that it can be deployed in more than one configuration. Each configuration specifies
the Java virtual machine features and a set of APIs that the profile implementer (and the applications using that
profile) can safely assume to be present on all devices when shipped from the factory. Profile implementers
must design their code to stay within the bounds of the Java virtual machine features and APIs specified by that
configuration. In its simplest terms, a configuration is a contract between a profile implementer and a device’s
Java virtual machine. The virtual machines of all the devices in the market segment agree to implement all the
features defined in the configuration. And the profile implementers agree to use only those features defined in
the configuration. Thus, portability is achieved between the profile and the devices served by that configuration.

New devices can take advantage of existing profiles. And new profiles can be installed on existing devices.
In our example above, each of the three profiles (for cell phones, washing machines, and intercommunicating
toys) would most likely be built upon the same configuration, the CLDC. This configuration provides all the
basic functionality to serve the needs of each of these, and perhaps many more, profiles.

Currently, the goal is to define two standard J2ME configurations :

• Connected, Limited Device Configuration (CLDC).


The market consisting of personal, mobile, connected information devices is served by the CLDC.
This configuration includes some new classes, not drawn from the J2SE APIs, designed specifically to
fit the needs of small-footprint devices.

• Connected Device Configuration (CDC).


The market consisting of shared, fixed, connected information devices is served by the
Connected Device Configuration (CDC). To ensure upward compatibility between configurations, the
CDC shall be a superset of the CLDC.
KVM:
The KVM is a compact, portable Java virtual machine specifically designed from the ground up for small,
resource-constrained devices. The high-level design goal for the KVM was to create the smallest possible
“complete” Java virtual machine that would maintain all the central aspects of the Java programming language,
but would run in a resource-constrained device with only a few hundred kilobytes total memory budget. More
specifically, the KVM was designed to be:

• Small, with a static memory footprint of the virtual machine core in the range of 40
kilobytes to 80 kilobytes (depending on compilation options and the target platform,)
• clean, well-commented, and highly portable,
• modular and customizable,
• as “complete” and “fast” as possible without sacrificing the other design goals.

The “K” in KVM stands for “kilo.” It was so named because its memory budget is measured in kilobytes
(whereas desktop systems are measured in megabytes). KVM is suitable for 16/32-bit RISC/CISC
microprocessors with a total memory budget of no more than a few hundred kilobytes (potentially less than 128
kilobytes). This typically applies to digital cellular phones, pagers, personal organizers, and small retail payment
terminals. The minimum total memory budget required by a KVM implementation is about 128 kB, including
the virtual machine, the minimum Java class libraries specified by the configuration, and some heap space for
running Java applications. A more typical implementation requires a total memory budget of 256 kB, of which
half is used as heap space for applications, 40 to 80 kB is needed for the virtual machine itself, and the rest is
reserved for configuration and profile class libraries.

A simple KVM implementation without system class pre linking support needs more volatile memory than
a KVM implementation with system classes (or even applications) preloaded into the device. The actual role of
a KVM in target devices can vary significantly. In some implementations, the KVM is used on top of an
existing native software stack to give the device the ability to download and run dynamic, interactive, secure
Java content on the device. In other implementations, the KVM is used at a lower level to also implement the
lower-level system software and applications of the device in the Java programming language. Several
alternative usage models are possible. At the present time, the KVM and CLDC are closely related. CLDC runs
only on top of KVM and CLDC is the only configuration supported by KVM. However, over time it is expected
that CLDC will run on other J2ME virtual machine implementations and that the KVM may perhaps support
other configurations as they are defined.

Midlet:
A MIDlet is an application that uses the Mobile Information Device Profile (MIDP) of the Connected
Limited Device Configuration (CLDC) for the Java ME environment.

Lifecycle:
MIDlet application is an applet that runs in small devices. Like an applet the midlet has a life cycle.
The core package which addresses the midlet life cycle is javax.microedition.midlet. Each state of life cycle is
notified to Application Management Software(AMS) and the AMS acts appropriately. AMS is the device
software that handles the midlet lifecycle.

Java Application Descriptor file and Java Archive are the two components that any MIDlet suite is
delivered. The JAD file describes the MDIlet suite. The description comprises of the MIDlet suite’s name,
location and size of the JAR file and other configuration and profile requirements.

Steps:

1. The MIDlet life-cycle is fundamental to creating any MIDlet.


2. The life-cycle defines the execution states of a MIDlet creation, start, pause, and exit.
3. A MIDlet is either in the active state or the paused state.
4. When it is first loaded by the MIDP runtime environment, it will be in the paused state.
5. The runtime will generally call the method startApp() to signal that the MIDlet should now activate itself.
6. Whenever the application is idle, the runtime can put the MIDlet back into the paused state.
7. When it is paused, the application will not receive user interface events.
8. The runtime will call pauseApp() to indicate that it has done this.
9. When the operator is finished with the MIDlet, the runtime will destroy it.
10. Before it does this, it calls the method destroyApp() method.
11. The MIDlet must deallocate resources here as it does when it enters the paused state.
12. In the MIDP documents, `destroyed' is described as being one of the states that the MIDlet may be in.
States:

AMS interacts with the MIDlet application in loading and unloading the MIDlet using the MIDlet's life cycle
methods and thus affecting the following midlet states.

• Paused State
• Active State
• Destroyed State

Once a MIDlet has been instantiated, it resides in one of three possible states. A state is designed to ensure that
the behavior of an application is consistent with the expectations of the end-users and device manufacturer.

Initialization of the application should be short; it should be possible to put an application in a non-active state;
and it should also be possible to destroy an application at any time. Therefore, three valid MIDlet states exist.

PAUSED

The MIDlet has been initialized, but is in a dormant state. This state is entered in one of four ways:

• after the MIDlet has been instantiated by the AMS invoking its constructor; if an exception occurs, the
destroy state is entered

• from the ACTIVE state, if the pauseApp() method is called by the AMS

• from the ACTIVE state, if the startApp() method has been called but an exception has been thrown

• from the ACTIVE state, if the notifyPaused() method has been invoked and successfully returned.

When a well-written MIDlet is paused, it should generally release any shared resources.

ACTIVE

The MIDlet is functioning normally. This state is entered after the AMS has called the startApp() method.
The startApp() method can be called on more than one occasion during the MIDlet lifecycle.

DESTROYED

The MIDlet has released all resources and terminated. This state, which can only be entered once, is
entered for the following two reasons:

• the destroyApp(boolean unconditional) method has been called by the AMS and returned successfully; if
the unconditional argument is false a MIDletStateChangedException may be thrown and the MIDlet will not move
to the DESTROYED state; the implementation of the destroyApp() method should release all resources and
terminate any running threads

• when the notifyDestroyed() method successfully returns; the application should release all resources and
terminate any running threads prior to calling notifyDestroyed().
MIDlet Lifecycle Methods:
The javax.microedition.midlet.MIDlet abstract class defines three lifecycle methods:

pauseApp() – this method is called by the AMS to indicate to the MIDlet that it should enter the PAUSED
state, releasing all shared resources and becoming passive.

startApp() – this method is invoked by the AMS to signal to the MIDlet that it has moved from the PAUSED to
the ACTIVE state. The application should acquire any resources it requires to run and then set the current
display.

destroyApp() – this method is called by the AMS to indicate to the MIDlet that it should enter the
DESTROYED state; all persistent and state data should be saved and all resources that have been acquired
during its lifecycle should be released at this point; generally, a well-written MIDlet will start up in the state it
was in prior to being shut down.

Example:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class HelloMidlet extends MIDlet
{
private Display display;
public void HelloMidlet(){}
public void startApp()
{
display=Display.getDisplay(this);
System.out.println ("Hello world ");
display.setCurrent(form);
}
public void pauseApp(){ }
public void destroyApp(boolean unconditional){}
}
J2ME USER INTERFACE:

User-interface requirements for small handheld devices are different from personal computers. Because
comparatively the display size of handheld devices is smaller. In J2ME,the CLDC itself does not define any
GUI functionality. The official GUI classes for the J2ME are included in profiles such as the MIDPand are
defined by the Java Community Process (JCP). The GUI classes in the MIDP are not based on theAbstract
Window Toolkit (AWT). The limited CPU memory of handheld devices, cannot handle the AWT. The MIDP
contains its own GUI guidelines. The MIDP GUI consists of high-level and low-level APIs, each with their
own set of events.

Device Display Hierarchy:

• Display Object
o Displayable Object
• DISPLAYABLE : Screen Object
• TextBox Object
• Alert Object
• List Object
• Form Object
• FORM : Item Object
• ChoiceGroup Object
• DateField Object
• Guage Object
• Image and ImageItem Object
• StringItem Object
• TextField Object

High-Level API
The high-level API is designed for applications whose client parts run on mobile information devices where
portability is important. To achieve portability, the API employs a high-level abstraction and gives you little
control over its look and feel. For example, you cannot define the visual appearance (shape, color, or font) of
components. Interaction with components is encapsulated by the implementation and the application is not aware
of such interactions.
When you use the high-level API, the underlying implementation does the necessary adaptation to the device's
hardware and native user interface style. The high-level API is implemented by classes that inherit from the
Screen class.

Low-Level API
The low-level API provides little abstraction. It is designed for applications that need precise placement and
control of graphic elements and access to low-level input events. This API gives the application full control over
what is being drawn on the display. The Canvas and Graphics classes implement the low-level API.

High-level API:

Screen is also the name of a class in the javax.microedition.lcdui package. In MIDP 2.0, the direct subclasses
ofScreen are:

• Alert - A Screen that shows data to the user and waits for a certain period of time before
proceeding to the next Displayable.
• Form - A Screen that contains an arbitrary mixture of items: images, read-only text fields, editable
text fields, editable date fields, gauges, choice groups, and custom items.
• List - A Screen containing a list of choices.
• TextBox - A Screen that allows the user to enter and edit text
Alert:

Alerts are best used in informational or error messages that stay on the screen for a short period of time
and then disappear.
The Alert class has two constructors:

• Alert (String title)

• Alert (String title, String alertText, Image image, AlertType type)

Title: sets the title for the alert screen


alertText: can be used to add more information to be displayed within the alert
image: allows you to display an specific image for the Alert.
Type: it is an identifier for the type of Alert we want to create, the values are static finals from the
AlertType class:

ALARM,
CONFIRMATION,
ERROR,
INFO and
WARNING.
The Alert object has a method called: setTimeout that allows you to define how much time the alert will be
shown. An special value shall be used when the alert is expecting an action from the user, and in that case you
should set the value to Alert.FOREVER.

Example: To display date and time using Alert

import java.util.Date;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;

public class DateTimeApp extends MIDlet


{
Alert timeAlert;
public DateTimeApp()
{
timeAlert = new Alert("Alert!");
timeAlert.setString(new Date().toString());
}
public void startApp()
{
Display.getDisplay(this).setCurrent(timeAlert);
}
public void pauseApp()
{}
public void destroyApp(boolean unconditional)
{}
}

List:
A list contains one or more choices (elements), which must have a text part, an optional image part. This
class extends the Screen class and implements the interface Choice. This object allows us to create screens with a
list of options to select.

The List class has two constructors:

List(String title, int listType)

List(String title, int listType, String[] elements, Image[] images)

The listType defines which type of List we want to create an can be:

• EXLUSIVE,

• MULTIPLE and

• IMPLICIT.

An exclusive List, means that only one option can be selected.

An implicit List, means that the selection of an option triggers an event.

A multiple List, means that many options can be selected at the same time.
create a list in one of two ways.
• Create an list that contains no elements, and then append or insert individual elements.
• Create the elements beforehand and then create a list with these elements.
delete elements using delete(int index) or deleteAll(). List index starting at 0.

Example:

import javax.microedition.lcdui.List;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
public class ListExample extends MIDlet
{
List fruitList1;
List fruitList2;
public ListExample()
{
fruitList1 = new List("Select the fruits you like", Choice.MULTIPLE);
fruitList1.append("Orange", null); fruitList1.append("Apple", null);
fruitList1.insert(1, "Mango", null); // inserts between Orange and Apple
String fruits[] = {"Guava", "Berry", "Kiwifruit"};
fruitList2 = new List( "Select the fruits you like - List 2", Choice.IMPLICIT,
fruits, null);
}
public void startApp()
{
Display display = Display.getDisplay(this);
display.setCurrent(fruitList1);
try
{
Thread.currentThread().sleep(3000);
}
catch(Exception e) {}
display.setCurrent(fruitList2);
}
public void pauseApp() { }
public void destroyApp(boolean unconditional) { }
}

TextBox:
Text is entered by the user using a textbox. TextBox class extends the Screen class and allows us to create screens
with a text editor.

The TextBox class has a constructor like this:

• TextBox (String title, String text, int size, int restrictions)


String title - the title text to be shown with the display.

String text - the initial contents of the text editing area.

int maxSize - the maximum capacity in characters.


int constraints - The restrictions are some validations that the textbox will perform or allow on the entered text. The
restrictions include:

EMAILADDR,
NUMERIC,
PASSWORD,
PHONENUMBER
URL
DECIMAL

Similarly, there are six constraint settings that affect the display. These are:

PASSWORD,
UNEDITABLE,
SENSITIVE,
NON_PREDICTIVE,
INITIAL_CAPS_WORD, and
INITIAL_CAPS_SENTENCE.

To set the contents of a textbox, you can use a couple of methods. Use setString(String text) to set the
contents with a String value. Use insert(String text, int position) to position text where to insert.

Example: To display name and pin


import javax.microedition.lcdui.TextBox;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
public class TextBoxExample extends MIDlet
{
private TextBox txtBox1;
private TextBox txtBox2;
public TextBoxExample()
{
txtBox1 = new TextBox( "Your Name?", "", 50, TextField.ANY);
txtBox2 = new TextBox( "Your PIN?", "", 4, TextField.NUMERIC |
TextField.PASSWORD);
}
public void startApp()
{
Display display = Display.getDisplay(this);
display.setCurrent(txtBox1);
try
{
Thread.currentThread().sleep(5000);
} catch(Exception e) {}
txtBox1.setString("Bertice Boman");
try
{
Thread.currentThread()
Sleep(3000);
} catch(Exception e) {} //inserts 'w' at the 10th index to make the name
Bertice Bowman
txtBox1.insert("w", 10);
try
{
Thread.currentThread().sleep(3000);
} catch(Exception e) {}
display.setCurrent(txtBox2);
}
public void pauseApp() { }
public void destroyApp(boolean unconditional) { }
}

Form:
A Form is a Screen that contains an arbitrary mixture of items: images, read-only text fields, editable text
fields, editable date fields, gauges, choice groups, and custom items. In general, any subclass of the Item class may
be contained within a form. The implementation handles layout, traversal, and scrolling.

The Form class has two constructors:


Public Form(String title);
Public Form(String title, Item[] items);

The Form has three methods that allows items to be added at the end of list.
Public void append(Item item);
Public void append(Image image);
Public void append(String string);

Item defines following two methods:


• void setLabel(String) and
• String getLabel()
StringItem:
An item that allows a text string to be placed in the user interface. A simple (labeled) piece of text
Eg..
Form form = new Form("Form Title");
StringItem stringItem =new StringItem("Label: ", "text");
form.append(stringItem);

Methods:
• String getText(), String getLabel()
• void setText(String), void setLabel(String)

ImageItem:
An object of the ImageItem class is an Item object that can contain a reference to an Image object.
Eg..
ImageItem imageItem = new ImageItem("ImageItem", redBallImage, "Alt Text");
form.append(imageItem);

TextField:
A single line input much like full screen TextBox.
• Editable field with a label
• Similar to TextBoxes

Constructor:
public TextField(String label, String text, int maxSize, int constraints)
eg:

TextField tf =new TextField("Enter Email: ","",50,TextField. EMAILADDR |TextField. NON_PREDICTIVE)

DateField:
A version of TextFiled that is specialized for the input of dates. It includes a visual helper simplifies the
process of choosing a date.
• Allows users to enter dates
• Different modes
DATE displays an editable date.
TIME displays an editable time.
DATE_TIME displays both a date and a time.

Constructor:
public DateField(String label,int mode)

Methods:
public Date getDate()
public void setDate(Date date)
eg..
DateField dateField = new DateField("DateField", DateField.DATE);
form.append(dateField);

ChoiceGroup:
A component that provides a set of choices that may or may not be mutually exclusive and therefore may
operate either as a collection of checkboxes or radio buttons.

• User selects item(s) from choices


• Very similar to Lists
Except no Implicit type
o instead use ChoiceGroup.POPUP

Constructor:
public ChoiceGroup(String label, int choiceType, String[] stringElements, Image[] imageElements)

Gauage:
A component that can be used to show the progress of an ongoing operation or allow selection of a value
from a contiguous range of values.
Constructor:
Public Gauage(String label, boolean interactive, int maxValue,
int initialValue)

Eg..
Gauge gauge01 = new Gauge("Gauge #1",true,6,3);
form.append(gauge01);

Example: for Form creation


import javax.microedition.lcdui.Display;

import javax.microedition.lcdui.Form;
import javax.microedition.midlet.MIDlet;

import javax.microedition.lcdui.Item;

import javax.microedition.lcdui.Image;

import javax.microedition.lcdui.ImageItem;

import javax.microedition.lcdui.Choice;

import javax.microedition.lcdui.ChoiceGroup;

import javax.microedition.lcdui.DateField;

import javax.microedition.lcdui.Gauge;

import javax.microedition.lcdui.StringItem;
import javax.microedition.lcdui.TextField;

public class Form01 extends MIDlet

Image redBallImage;

Form form;
public Form01()

{//constructor

redBallImage = Image.createImage("/Form01/redball.PNG");

System.out.println("Create Form");

form = new Form("Form Title");


//Append a String to the form. This is a shorthand for StringItem

form.append("This is a String.\n");

//Append a StringItem to the form.


StringItem stringItem = new StringItem("This is a StringItem","StringItem text\n");

form.append(stringItem);

//Put three images in the form in shorthand

form.append(redBallImage);

//Create and append an ImageItem.

ImageItem imageItem = new ImageItem("ImageItem",redBallImage, "Alt Text");

form.append(imageItem);
//Create a ChoiceGroup and append it to the Form. Set the selection mode to EXCLUSIVE.
ChoiceGroup choiceGroup = new ChoiceGroup("ChoiceGroup", Choice.EXCLUSIVE);

choiceGroup.append("Zero",redBallImage);
choiceGroup.append("One",greenBallImage);

choiceGroup.append("Two",blueBallImage);

form.append(choiceGroup);

//Create a new DateField and append it to the form.

DateField dateField = new DateField("DateField", DateField.DATE);


form.append(dateField);

//Create two Gauges. The first Gauge is interactive. The second is not interactive.

Gauge gauge01 = new Gauge("Gauge #1",true,6,3);

form.append(gauge01);

Gauge gauge02 = new Gauge("Gauge #2",false,6,2);


form.append(gauge02);

//Create a TextField and append it to the form.

TextField textField = new TextField("TextField","Initial Text",30, TextField.ANY);

form.append(textField);

}//end constructor

public void startApp()


{

//Make the Form the current display.

System.out.println("Display form");

Display.getDisplay(this).setCurrent(form);

//Sleep for 100 seconds.

try{Thread.currentThread().sleep(100000);

} catch(Exception e){}

//Enter the destroyed state.

this.destroyApp(true);
}//end startApp

public void pauseApp(){}

public void destroyApp(boolean unconditional)

System.out.println("Destroy MIDlet");

notifyDestroyed();
}

Event Handling:
There are two types of Events:
• Command events – it is triggered by key presses on the device.
• Item events – Item events are the result of visual components changing on the
display.
Commands Events:
Commands:
Commands are a feature of the Displayable class, so we can add commands to any user interface.
Creating Commands:

Public Command(String label,int type,int priority);

Label – text that will be used to represent the command


Type – type of command operation

Command Types:
OK – agreement by the user for some operation performed.
BACK – Replaces the currently displayed screen with the one that preceded it.
CANCEL – Abandons an operation before it has been initiated.
STOP – Stops an operation that is already in progress.
EXIT – Terminates the midlet.
HELP – Requests general or context-sensitive help.
SCREEN – relates to the function of the current screen.

Adding Commands:

Public void addCommand(String label, CommandType cmd, int priority);

Label – label of the command


Cmd - Type of command
Priority – priority of the command

Eg..

Command exitcommand = new Command( “Exit”, Command.EXIT,0);


Form1.addCommand(exitcommand);

Responding to user activation of Commands:

In order to be notified when the user activates a Command, it needs to register a CommandListner with
the Displayable to which the Command was added by invoking its setCommandListener() method:

Public void setCommandListener( CommandListener 1);

CommandListener is an interface with a single method:

Public void CommandAction(Command c, Displayable d);


This method is called when any Command on the Displayable is activated. The first argument
command is allows to determine which operation the user wants to perform. The Displayable argument is used
to add same Command to more than one screen.

Example Program:

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.*;

public class Commandsmidlet extends MIDlet implements CommandListener


{
private TextBox txtBox1;
private Command exitcmd;
private Command okcmd;
private Display d;
public Commandsmidlet()
{
d = Display.getDisplay(this);
txtBox1 = new TextBox( "Your Name?", "", 50, TextField.ANY);
exitcmd = new Command( “Exit”, Command.EXIT,0);
okcmd = new Command( “OK”, Command.OK,0);
txtBox1.addCommand(exitcmd);
txtBox1.addCommand(okcmd);
txtBox1.setCommandListener(this);

}
public void startApp()
{
d.setCurrent(txtBox1);
}
public void pauseApp(){}
public void destroyApp(boolean unconditional){}
public void commandAction(Command c, Displayable s)
{
if (c == exitcmd)
{
notifyDestroyed();
}
else if(c==okcmd)
{
System.out.println(“OK pressed”);
}
}
}

Item Events:
In Form, changes in the state of Items that accept user input are notified to an ItemStateListener.
ItemstateListener is an interface with a single method, which is called when any Item on the Form has a state change
to report:
public void itemStateChanged(Item item);

This method is called when internal state of an Item has been changed by the user. This happens when the user:

• changes the set of selected values in a ChoiceGroup;


• adjusts the value of an interactive Gauge;
• enters or modifies the value in a TextField;
• enters a new date or time in a DateField;

An ItemStateListener interface is registered using following Form method:

public void setItemStateListener( ItemStateListener 1);


Example Program:

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

public class ItemStateListenerMIDlet extends MIDlet


{
private Display display;
private Form form;
private Date date = new Date();
private Calendar calendar;
private DateField today;

public ItemStateListenerMIDlet()
{
display = Display.getDisplay(this);
}

public void startApp()


{
form = new Form("ItemStateListener");
ItemStateListener listener = new ItemStateListener()
{
Calendar calendar = Calendar.getInstance(TimeZone.getDefault());

public void itemStateChanged(Item item)


{
calendar.setTime(((DateField)item).getDate());
}
};
form.setItemStateListener(listener);
today = new DateField("Today's Date:", DateField.DATE);
today.setDate(date);
form.append(today);
display.setCurrent(form);
}

public void pauseApp()


{
}

public void destroyApp(boolean unconditional)


{
notifyDestroyed();
}
}
RMS ( Record Management System):

The MIDP supports persistence of application data through its Record Management System(RMS).
The javax.microedition.rms package definespersistent APIs.

Each MIDP-compliant device maintains a dedicated area of device memory for persistent application data
storage. MIDlet data stored here persists across multiple invocations of the applications that use it. Both the physical
location and the size of the data store are device dependent.
The RMS API abstracts the device-dependent details of the storage area and access to those details, and it
provides a uniform mechanism to create, destroy, and modify data. This ensures portability of MIDlets to
different devices.
RMS Data Storage Model
The RMS supports the creation and management of multiple record stores, shown in Figure below.
Arecord store is a database whose central abstraction is the record. Each record store consists of zero or more
records. A record store name is case sensitive and can consist of a maximum of 32 Unicode characters. A record
store is created by a MIDlet.

MIDlets within the same MIDlet suite can share one another's record stores. A MIDlet suite defines a name
space for record stores; a record store must have a unique name within a MIDlet suite. The same name can be
used in different MIDlet suites, however.
MIDlets can list the names of all the record stores available to them. They can also determine the amount
of free space available for storing data. Incidentally, you should be aware that when all MIDlets in a MIDlet
suite are removed from a device, the device AMS removes all record stores in the MIDlet suite namespace. All
persistent data will be lost. For this reason, you should consider designing applications to include a warning or
confirmation that requires users to acknowledge that they understand the potential loss of data when they
remove applications. Applications might also include a mechanism to back up the records in a data store to
another location. This might require server side support.

Record Stores

The record stores have the following properties:

• Each RecordStore is composed of zero or more records.


• RecordStore names are case sensitives
• Within the same suite, there cannot be two RecordStores with the same name.
• If a MIDlet suite is deleted, all the RecordStores of that suite are deleted.
• It is possible for a MIDlet to acces a RecordStore from another suite, but only when the suite has given
access to that RecordStore.

Each RecordStore handles multiple records, and each record is formed of: a RecordID and byte array.

Creating a record store:


No constructor exists for creating a record store. Instead, we use a set of three dual-purpose methods to
create and/or open record stores.
RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary)
RecordStore openRecordStore(String recordStoreName, boolean createIfNecessary, int authmode,
boolean writable)
RecordStore openRecordStore(String recordStoreName, String vendorName, String suiteName)

The first method opens the named record store if it exists. If the named record store does not exist, and if
the parameter createIfNecessary is set to true, the method can be used to create a new (named) record store.
In second method first parameter specifies whether or not only those MIDlets in the same suite can
access the record store. The second one specifies whether MIDlets that have access to the record store, can create
new records.
The last method provides a means for a MIDlet to open a record store in another MIDlet suite.
Eg..
private RecordStore rs = null; // Record store
public void openRecStore()
{
// Create record store if it does not exist
rs = RecordStore.openRecordStore(REC_STORE, true);
}

Closing Record Stores

Like in JDBC you will need to do some cleaning up when the Record Store is not in use. It is very
important to close an idle Record Store as RMS interactions eat up a lot of device runtime cache. To close a Record
Store call closeRecordStore() .

rs.closeRecordStore();

Deleting a record store


When a MIDlet suite is deleted from a device, any record stores created by the suite will also be
removed. And also Record store can be deleted by deleteRecordStore() method.
RecordStore.deleteRecordStore("REC_STORE");

The RMS defines the following conceptual operations on an individual record store:
• Add a record.
• Delete a record.
• Change a record.
• Look up (retrieve) a record.
• Enumerate all records.

Records are uniquely identified by a record ID, which is the only primary key type supported. The type
of all record ids is the Java built-in type int. The RMS has no support for features—such as tables, rows,
columns, data types, and so forth—that are present in relational databases.

Records

A record is a byte array of type byte []. The RMS doesn't support the definition or formatting of fields
within a record. Your application must define the data elements within a record and their format.

The reader of a record, therefore, must be aware of the format that was used to write the record. Because
a record is simply a byte array, applications must convert data from arbitrary types to bytes when writing
records, and they must convert from bytes to those types upon reading the data.

Adding Records:

To add a new record, supply the byte array to the addRecord() method:

public int addRecord(byte[] data, int offset, int numbytes)

The added record will be numbytes long, taken from the data array starting at offset. The new record’s ID is
returned. Most other record operations need this ID to identify a particular record.

Eg..
String record=”This is a record”;
byte[] data = record.getBytes();
int id=rs.addRecord(data,0,data.length);

Deleting Records:

A record can be deleted using the deleteRecord() method. This deleted record and its ID is lost forever.
We cannot reuse the deleted record ID.

public void deleteRecord(int recordId)


eg..
rs.deleteRecord(1);

Updating Records:

The records can be referenced by the recordId's and can be queried and updated.

• Use getRecord(int recordId, byte[] buffer, int offset) to get the record with recordId. The record is stored in
the variable buffer from the initial offset.
• byte[] getRecord(int recordId) is similar to the above method but you cannot specify the initial offset. Here
the offset is always 0.
• setRecord(int recordId, byte[] newData, int offset, int numBytes) is used to update the record at specified
record ID. The updation is done with the record newData with offset as its starting index and numBytes as
data length.

Eg..

String str = "updating records";


Byte byteUpdateSalsa = str.getBytes();
rs.setRecord(1, bytedata, 0, bytedata.length());

Retrieving record:
Retrieve a record by supplying the record ID to the following method:

public byte[] getRecord(int recordId)

This method returns a newly created byte array containing the record with the requested ID.

Example: simple read and write of RMS in J2ME


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

public class ReadWriteRMS extends MIDlet


{
private RecordStore rs = null;
String REC_STORE = "ReadWriteRMS";
public void startApp()
{
openRecStore();
writeRecord("Core J2ME Technology");
writeRecord("J2ME Wireless Toolkit");
readRecords();
closeRecStore();
deleteRecStore();
}

public void pauseApp(){}


public void destroyApp(boolean unconditional)
{
notifyDestroyed();
}
public void openRecStore()
{
try{
rs = RecordStore.openRecordStore(REC_STORE, true );
}catch (Exception e){}
}
public void closeRecStore()
{
try{
rs.closeRecordStore();
}catch (Exception e){}
}
public void deleteRecStore()
{
if (RecordStore.listRecordStores() != null)
{
try{
RecordStore.deleteRecordStore(REC_STORE);
}catch (Exception e){}
}
}
public void writeRecord(String str)
{
byte[] rec = str.getBytes();
try{
rs.addRecord(rec, 0, rec.length);
}catch (Exception e){}
}

public void readRecords()


{
try{
byte[] recData = new byte[5];
int len;
for(int i = 1; i <= rs.getNumRecords(); i++)
{
if(rs.getRecordSize(i) > recData.length)
{
recData = new byte[rs.getRecordSize(i)];
}
len = rs.getRecord(i, recData, 0);
System.out.println("------------------------------");
System.out.println("Record " + i + " : " + new String(recData, 0, len));
System.out.println("------------------------------");
}
}catch (Exception e){}
}
}

J2ME I/O and networking


The javax.microedition.io classes and interfaces handle the networking capability of the Mobile
Information Device Profile (MIDP), a platform for development of applications for mobile devices.
The java.io package, on the other hand, provides input/output (I/O) capability to MIDP. Its various classes and
interfaces provide for system input and output for data streams.

The J2ME Generic Connection Framework

The idea of the Generic Connection framework is to define the abstractions of the networking and file I/O
as general as possible to support a broad range of handheld devices, and leave the actual implementations of these
abstractions to individual device manufacturers. These abstractions are defined as Java interfaces. The device
manufacturers choose which one to implement in their MIDP based on the actual device capabilities.
There is 1 class (Connector) and 7 connection interfaces (
Connection, ContentConnection, DatagramConnection, InputConnection,OutputConnection, StreamConnection,
and StreamConnectionNotifier) defined in the Generic Connection framework. They can be found in
the javax.microedition.io package that comes with J2ME CLDC. There is no implementation of the connection
interfaces at the CLDC level. The actual implementation is left to MIDP.

The 7 connection interfaces define the abstractions of 6 basic types of communications: basic serial input,
basic serial output, datagrams communications, sockets communications, notification mechanism in a client-server
communication, and basic HTTP communication with a Web server.

The relationships between these interfaces are illustrated in the following diagram:

The Connector class is the core of Generic Connection framework. The open method in Connector class is
used to create all connection objects. Different types of communication can be created by the same method with
different parameters. The connection could be file I/O, serial port communication, datagram connection, or an http
connection depending on the string parameter passed to the method. Such design makes J2ME implementation very
extensible and flexible in supporting new devices and products.
Connector.open(String connect);
The parameter connect is a String variable. It has a URL-like format: {protocol}:[{target}][{params}].
protocol - dictates what type of connection will be created by the method.
There are several possible values for protocol:
file - indicates that the connection will be used for file I/O
socket - indicates that the connection will be used for serial port
communication
comm - TCP/IP socket communication
datagram - Datagram communication

http - indicates that the connection is created for accessing web servers.
target - can be a host name, a network port number, a file name, or a communication port number.
params - is optional, it specifies the additional information needed to complete the connect string.
Eg..

HTTP communication:

Connection hc = Connector.open("http://www.wirelessdevnet.com");

Stream-based Socket communication:

Connection sc = Connector.open("socket://localhost:9000");

Datagram-based socket communication:

Connection dc = Connector.open("datagram://:9000");

Serial port communication:

Connection cc = Connector.open("comm:0;baudrate=9000");

File I/O

Connection fc = Connector.open("file://foo.dat");

The Methods in the Connector Class

The Connector class is the only concrete class in Generic Connection framework in CLDC. It contains
seven static methods:
static Connection open(String connectString)

This method creates and opens a new Connection based on the connectString.

static Connection open(String connectString, int mode)

This method creates and opens a new Connection based on the connectString. The
additional mode parameter specifies the access mode for the connection. There are three access modes:
Connector.READ,
Connector.READ_WRITE, and
Connector.WRITE.
If mode is not specified, the default value is Connector.READ_WRITE. The validity of the actual setting is
protocol dependent. If the access mode is not allowed for a protocol, an IllegalArgumentException will be
thrown.
static Connection open(String connectString, int mode, boolean timeouts)
This method creates and opens a new Connection based on the connectString. The
additionaltimeouts parameter is a Boolean flag that dictates whether the method will throw a timeout
exceptionInterruptedIOException. The default timeouts value is false, which indicates that no
exception will be thrown.
static DataInputStream openDataInputStream(String connectString)
This method creates and opens a new DataInputStream based on the connectString.

static DataOutputStream openDataOutputStream(String connectString)

This method creates and opens a DataOutputStream from the connectString.


static InputStream openInputStream(String connectString)
This method creates and opens a new InputStream from the connectString.
static OutputStream openOutputStream(String connectString)
This method creates and opens a new OutputStream from the connectString.
The last four I/O stream-creation methods combine creating the connection and opening the input/output stream into
one step. For example, the following statement

DataInputStream dis = Connector.openDataInputStream(http://www.webyu.com);

is the equivalent of the following two statements:

InputConnection ic = (InputConnection)

Connector.open("http://www.webyu.com", Connector.READ, false);

DataInputStream dis = ic.openDataInputStream();

Example: HttpConnection
/**
* This sample code block demonstrates how to open an
* http connection, how to establish an InputStream from
* this http connection, and how to free them up after use.
**/
// include the networking class libraries
import javax.microedition.io.*;
// include the I/O class libraries
import java.io.*;
// more code here ...
// define the connect string with protocol: http
// and hostname: 64.28.105.110
String connectString = "http://64.28.105.110";
InputConnection hc = null;
DataInputStream dis = null;
// IOException must be caught when Connector.open() is called
try {
// an http connection is established with read access.
// The returned object is cast into an InputConnection object.
hc = (InputConnection)
Connector.open(connectString, Connector.READ, false);
// an InputStream is created on top of the InputConnection
// object for read operations.
dis = hc.openDataInputStream();
// perform read operations here ...
} catch (IOException e) {
System.err.println("IOException:" + e);
} finally {
// free up the I/O stream after use
try { if (dis != null ) dis.close(); }
catch (IOException ignored) {}
// free up the connection after use
try { if ( hc != null ) hc.close(); }
catch (IOException ignored) {}

Network programming using sockets is very straightforward in J2ME. The process works as follows:

1. A socket connection is opened with a remote server or another wireless device


usingConnector.open().
2. InputStream or OutputStream is created from the socket connection for sending or receiving data
packets.
3. Data can be sent to and received from the remote server via the socket connection by performing read or
write operations on the InputStream or OutputStream object.
4. The socket connection and input or output streams must be closed before exiting the program.

Eg..

import javax.microedition.io.*;
import java.io.*;
// more code here ...
// define the connect string with protocol: socket,
// hostname: 64.28.105.110, and port number: 80
String connectString = "socket://64.28.105.110:80";
OutputConnection sc = null;
DataOutputStream dos = null;
// IOException must be caught when Connector.open() is called.
try {
// a socket connection is established with the remote server.
sc = (OutputConnection) Connector.open(socketUrlString);
// an OutputStream is created on top of the OutputConnection
// object for write operations.
dos = sc.openDataOutputStream();
// perform write operations that send data to the remote server ...
}
catch (IOException e)
{
System.err.println("IOException caught:" + e)
}
finally
{
// free up the I/O stream after use
try { if (dos != null ) dos.close(); }
catch (IOException ignored) {}
// free up the socket connection after use
try { if ( sc != null ) sc.close(); }
catch (IOException ignored) {}
}
Sample Program
/** The following MIDlet application creates socket connection with a remote Web server at port 80, and
then sends an HTTP request to retrieve the Web page "index.html" via the connection. * */
import javax.microedition.midlet.*;
import javax.microedition.io.*;
import javax.microedition.lcdui.*;
import java.io.*;
public class SocketExample extends MIDlet {
// StreamConnection allows bidirectional communication
private StreamConnection streamConnection = null;
// use OutputStream to send requests
private OutputStream outputStream = null;
private DataOutputStream dataOutputStream = null;
// use InputStream to receive responses from Web server
private InputStream inputStream = null;
private DataInputStream dataInputStream = null;
// specify the connect string
private String connectString = "socket://64.28.105.110:80";
// use a StrignBuffer to store the retrieved page contents
private StringBuffer results;
// define GUI components
private Display myDisplay = null;
private Form resultScreen;
private StringItem resultField;
public SocketExample() {
// initializing GUI display
results = new StringBuffer();
myDisplay = Display.getDisplay(this);
resultScreen = new Form("Page Content:");
}
public void startApp() {
try {
// establish a socket connection with remote server
streamConnection = (StreamConnection) Connector.open(connectString);
// create DataOuputStream on top of the socket connection
outputStream = streamConnection.openOutputStream();
dataOutputStream = new DataOutputStream(outputStream);
// send the HTTP request
dataOutputStream.writeChars("GET /index.html \n");
dataOutputStream.flush();
// create DataInputStream on top of the socket connection
inputStream = streamConnection.openInputStream();
dataInputStream = new DataInputStream(inputStream);
// retrieve the contents of the requested page from Web server
int inputChar;
while ( (inputChar = dataInputStream.read()) != -1) {
results.append((char) inputChar);
}
// display the page contents on the phone screen
resultField = new StringItem(null, results.toString());
resultScreen.append(resultField);
myDisplay.setCurrent(resultScreen);
} catch (IOException e) {
System.err.println("Exception caught:" + e);
} finally {
// free up I/O streams and close the socket connection
try {
if (dataInputStream != null)
dataInputStream.close();
} catch (Exception ignored) {}
try {
if (dataOutputStream != null)
dataOutputStream.close();
} catch (Exception ignored) {}
try {
if (outputStream != null)
outputStream.close();
} catch (Exception ignored) {}
try {
if (inputStream != null)
inputStream.close();
} catch (Exception ignored) {}
try {
if (streamConnection != null)
streamConnection.close();
} catch (Exception ignored) {}
}
}
public void pauseApp() { }
public void destroyApp(boolean unconditional) { }
}
The program first opens a socket connection with the Web server http://www.webyu.com at port 80. It
sends an HTTP request to the Web server using the DataOutputStream established from the connection. It
receives the requested content from the Web server using the DataInputStream opened from the connection.
After the Web page content is completely received, the content is displayed on the emulator.

You might also like