Skip to main content

Preparing for the Mobile Application Developer Certification

Get certified as a SCMAD and gain more recognition in the mobile development community

C. Enrique Ortiz, Mobility Technologist and Writer, J2MEDeveloper.com
C. Enrique Ortiz co-designed the Sun Microsystems' Mobile Java Developer Certification Exam, and is an active participant in the wireless Java community and in various J2ME expert groups. He is a software architect and developer, and a wireless mobility technologist and writer who has authored and co-authored many publications. Enrique holds a B.S. in Computer Science from the University of Puerto Rico and has more than 15 years of software engineering, product development, and management experience.

Summary:  Learn how to become certified as a Java 2 Platform, Micro Edition (J2ME) mobile developer, an achievement that is recognized by peers and managers looking for experienced mobile developers. Getting ready requires knowledge of a lot of topics, though, and this article, presented by one of the designers of the certification, introduces you to these requirements.

Date:  15 Feb 2005
Level:  Introductory
Comments:  

The Sun Certified Mobile Application Developer (SCMAD) certification both educates the developer community on the J2ME technologies used for mobile application development, and establishes a minimum skill level for J2ME mobile developers. To prepare for the SCMAD, you must have knowledge of many topics. This article tells you what's important for you to know.

To take the SCMAD examination you must already be certified as a Sun Certified Programmer for the Java 2 Platform (see Resources for more information).

The SCMAD exam tests developers for their knowledge and ability to write mobile applications using J2ME and the technologies specified by Java Technology for the Wireless Industry (JTWI) specification (see Resources for more information). The exam consists of major topics taken from the following J2ME specifications:

  • JSR 185 - Java Technology for the Wireless Industry (JTWI)
  • JSR 30 - Connected Limited Device Configuration (CLDC) 1.0
  • JSR 139 - Connected Limited Device Configuration (CLDC) 1.1
  • JSR 118 - Mobile Information Device Profile 2.0 (MIDP). MIDP 2.0 superceded MIDP 1.0
  • JSR 120 - Wireless Messaging API(WMA) 1.1
  • JSR 135 - Mobile Media API (MMAPI) 1.1

A certified mobile application developer must be versed in the following topics:

  • The architecture of J2ME
  • The Java Technologies for Wireless Industry (JTWI)
  • The Connected Limited Device Configuration (CLDC) 1.0 and 1.1
  • The Mobile Information Device Profile (MIDP) 2.0
  • The MIDP application model
  • The MIDP high-level user interface API
  • The MIDP low-level user interface API
  • Networking and the Generic Connection Framework
  • MIDlet activation using the PushRegistry
  • MIDP Security
  • Managing data using the Record Store API
  • The MIDP gaming API
  • Media control using the Mobile Media API
  • Short messaging with the Wireless Messaging API
  • Application deployment and Over the Air Provisioning

Now, I'll define these topics in more detail.

The architecture of J2ME

The J2ME architecture is organized as a software stack consisting of configurations, profiles, optional packages, vendor-specific APIs, and applications, as shown in Figure 1.


Figure 1. J2ME architecture
The J2ME Architecture

At the bottom of the stack is the configuration, the foundation that provides the minimum, lowest common denominator Java Runtime Environment (JRE), which includes the Java Virtual Machine (JVM) and core Java platform libraries. A profile extends a configuration with higher-level functions and APIs that include advanced user interfaces, local storage, network application protocols, gaming, and media control. An example of a configuration is the Connected Limited Device Configuration (CLDC); a profile example is the Mobile Information Device Profile (MIDP). J2ME applications are at the top of the stack, above profiles.

Each software layer can define its own set of requirements. For example, a configuration specifies run-time requirements, which might be overridden by the high-level layers or by JTWI. An example of this is the CLDC, which specifies a minimum of 32 KB of RAM, a requirement the JTWI increases to 256 KB.

The J2ME architecture also defines optional packages, the standard APIs defined by the Java Community Process (see Resources) that extend the functions provided by profiles. The inclusion of an optional package, which, as the name implies, is optional, might increase the hardware requirements defined by configuration and profiles, which is the reason JTWI specifies minimum requirements for the handset. An example of an optional package is the Wireless Messaging API, discussed later in this article.

In addition to configurations, profiles, and optional packages, handset manufacturers might offer their own vendor-specific APIs to control device-specific features such as radio transceivers or thumb-operated keyboards; but these APIs are non-portable, and you should minimize their use if possible.


Java Technologies for the Wireless Industry

The exam tests you on the JTWI mandatory versus optional packages, requirements clarifications, and overall goal.

While the J2ME architecture specifies the organization and relationship between configurations, profiles, optional packages, and J2ME applications, the JTWI defines the minimum requirements and run-time characteristics that all compliant wireless devices must support. Figure 2 illustrates this.


Figure 2. JTWI software components
JTWI software components

JTWI defines the following mandatory specifications:

  • MIDP 2.0
  • CLDC 1.0 (Because CLDC 1.1 is a superset of CLDC 1.0, handset manufacturers might use CLDC 1.1 instead.)
  • WMA 1.1

JTWI then defines MMAPI 1.1 as the conditionally required specification. JTWI also clarifies a number of requirements that are loosely defined in the above-noted specifications by mandating minimum requirements for:

  • Display characteristics
  • Number of threads
  • Application and memory pre-allocation sizes
  • Run time environment
  • Media support
  • User interface behavior
  • MIDlet activation
  • Security and untrusted domains

The JTWI specification does a good job of documenting these clarifications and minimum requirements. Refer to the JTWI specification in Resources for more information.


The Connected Limited Device Configuration

The exam tests you on the concept of configurations and CLDC, the differences between CLDC 1.0 and 1.1, and how they compare to Java 2 Platform, Standard Edition (J2SE). The minimum configuration that all JTWI-compliant devices must support is CLDC 1.0. CLDC defines the minimum, lowest common denominator JRE as:

  • Java language, virtual machine, and core APIs
    • Subset of the J2SE 1.3.1 core system, data types, collection, input/output, and calendar/time classes
    • Limited set of exception classes and no support for asynchronous exceptions
    • No user-defined class loader
    • No thread-groups and daemon threads
    • No class finalization
    • No reflection
    • No direct access to native functions
    • Class verification through off-device preverification
  • Basic security
    • Sandbox model
    • Protection of java.* and javax.microedition.* system packages
    • Class loading only from MIDlet suite Java Archive (JAR) file
  • Networking
    • Introduction of the Generic Connection Framework
  • Internationalization
    • Support for Unicode 3.0 and ISO Latin-1

CLDC defines system properties that the application can query by calling the System.getProperty() method to discover system information such as the configuration and profile versions, and default character-encoding: microedition.platform, microedition.encoding, microedition.configuration, and microedition.profiles.

The CLDC application model is simple. An application is launched by calling its main method, public static void main(String[] args) and the application runs until it exits.

Because CLDC1.1 can be used instead of CLDC1.0, it is important to understand the differences between both. Some of the new features in CLDC 1.1 include:

  • Floating-point support, including the classes Float and Double, and methods such as sin, cos, and tan
  • Addition of weak references
  • Thread.getName(), NoClassDefFoundError, Boolean.TRUE, Boolean.FALSE, and other minor changes
  • Improved Calendar, Date and TimeZone
  • Memory budget raised from 160 KB to 192 KB

The CLDC specifications (see Resources) contain more information on these new features.


The Mobile Information Device Profile (MIDP) 2.0

The exam tests you on the concept of profiles, MIDP 2.0, and its advanced features.

J2ME profiles define advanced functions not found in configurations; for example, application models and APIs for user interface, data store, and networking. MIDP 2.0 defines the following functions and APIs:

  • Application model
  • User interface API
  • Record management storage API
  • Network protocols and advanced networking capabilities, including secure connections
  • A gaming and media API
  • Security policies and code signing
  • Application deployment and over-the-air provisioning

There is a lot of information related to MIDP, and the following sections introduce these topics in more detail.

MIDP application model

The exam tests your knowledge of the MIDP application model's run-time environment, packaging, and life cycle.

MIDP applications are referred to as MIDlets. MIDlets are managed by the Application Management Software (AMS), which is software on the device that is responsible for the installation, launching and execution, and overall life cycle of MIDlets. The AMS provides access to classes and APIs such as CLDC, the VM, and optional packages.

MIDlet applications are packaged into MIDlet suites. A MIDlet suite package consists of a Java Archive and an optional Java Application Descriptor (JAD), as shown in Figure 3.


Figure 3: Contents of a MIDlet suite
Contents of a MIDlet suite

A JAD file is a descriptor text file that contains all the attributes, some required and some optional, that are used to retrieve and install a MIDlet suite's JAR. JAD files are optional, but their usage is highly recommended because they describe the MIDlet suite's installation requirements. The file extension for a JAD file is .jad, and its MIME type is text/vnd.sun.j2me.app-descriptor. The JAR file is a standard Java Archive, and it contains the MIDlet suite's classes, resources, and manifest. The JTWI defines the following minimum file sizes that must be supported by compliant wireless devices:

  • Java Application Descriptor (JAD) - 5 KB
  • MIDlet suite (JAR) Size - 64 KB

The following are required application attributes, some of which must be defined in the JAD file, and others in the JAR manifest:

  • MIDlet-Name: Mandatory in JAD, optional in manifest.
  • MIDlet-Version: Mandatory in JAD, optional in manifest. Format is Major.Minor[.Micro].
  • MIDlet-Vendor: Mandatory in JAD, optional in manifest.
  • MIDlet-Jar-URL: Mandatory in JAD.
  • MIDlet-Jar-Size: Mandatory in JAD.
  • MIDlet-<n>: For each MIDlet. Optional in JAD, required in manifest.
  • MicroEdition-Profile: Optional in JAD, mandatory in manifest.
  • MicroEdition-Configuration: Optional in JAD, mandatory in manifest.

The following are optional attributes that can be defined in the JAD or manifest:

  • MIDlet-Description: application description.
  • MIDlet-Icon: application's icon.
  • MIDlet-Info-URL: URL for MIDlet suite information page.
  • MIDlet-Data-Size: Minimum required data space.
  • MIDlet-Permissions: Requested permissions.
  • MIDlet-Permissions-Opt: Requested optional permissions.
  • MIDlet-Push-<n>: <ConnectionURL>, <MIDletClassName>, <AllowedSender>. Push static registration.
  • MIDlet-Install-Notify: URL for installation notifications..
  • MIDlet-Delete-Notify: URL for deletion notifications.
  • MIDlet-Delete-Confirm: User prompt for deletions.

The following two attributes are mandatory for trusted MIDlets, and must be defined in the JAD file:

  • MIDlet-Jar-RSA-SHA1: defines the JAR signature
  • MIDlet-Certificate-<n>-<m>: defines the public key certificate

Additionally, applications can define their own attributes, as long as they don't begin with MIDlet- or MicroEdition-, which are reserved keywords.

The MIDlet suite can consist of one or more MIDlets, each described by a MIDlet-<n> attribute. All the MIDlets within the MIDlet suite have access to all the files in the JAR with the exception of classfiles, which are only accessible for execution purposes and can't be read as resources. Resource files, which can be used for messages, images, or even sound files, can be read using the java.lang.Class.getResourceAsStream() method. MIDlets don't have access to files or resources outside the ones found in the MIDlet suite's JAR file.

The MIDlet life cycle is managed by the AMS as a state machine, with three defined states: paused, active, and destroyed. The AMS transitions the MIDlet to each state by invoking the life cycle methods pauseApp(), startApp(), and destroyApp(), respectively. Each life cycle method must implement logic to manage the appropriate state.

MIDlet suite installation and over-the-air provisioning

The exam also tests your knowledge of the MIDlet suite (application) installation process, including MIDlet suite discovery, over-the-air provisioning and installation, and status notifications.

MIDlet suite installation begins with discovery, searching for an application of interest. Discovery is initiated by the user and assisted by the AMS and a Discovery Application (DA), typically an external Web browser that lets the user search for and select an application for download and installation.

After the application has been selected for installation, the download process is initiated. Download occurs over HTTP 1.1 and authentication might be required; authentication is based on HTTP Basic Authentication (see Resources). In a typical scenario, a JAD descriptor file has been defined for the MIDlet suite. The JAD file is downloaded and its attributes used for MIDlet suite validation, including memory and storage resource availability.

In the absence of a JAD file, or after the JAD file has been downloaded, the JAR file is downloaded and installed. A number of checks are done during installation, including the validation of attributes and checking space requirements. If the application is trusted, the MIDlet suite is validated for authenticity. An error during installation results in the MIDlet suite failing to install.

If the MIDlet suite installation is an update to an existing MIDlet suite, as indicated by the MIDlet suite name, origin, and version number, the user is notified of this condition prior to the update installation; the user can then choose to proceed or cancel the installation. During an update, the contents of the record store are maintained if the new MIDlet suite came from the same place as the one being updated, and if their signers are the same.

If the attribute MIDlet-Install-Notify is defined in the JAD file, the AMS uses this URL to send an installation notification (status code and message) over HTTP. Failing to send this notification doesn't prevent the MIDlet from being installed and available to the user.

MIDlet suite execution

Executing a MIDlet suite consists of invoking a MIDlet and loading any appropriate and dependant classes. If the MIDlet suite consists of more than one MIDlet, the AMS presents the list of available MIDlets to the user for selection.

MIDlet suite removal

Removing a MIDlet suite requires user confirmation. If the attribute MIDlet-Delete-Confirm is defined, the AMS uses its value to prompt the user for confirmation. Removing a MIDlet suite results in its record stores also being removed.

If the attribute MIDlet-Delete-Notify is defined, the AMS uses this URL to send a delete notification (status code and message) over HTTP. Failing to send this notification doesn't prevent the MIDlet from being removed.

MIDP security

The exam tests your knowledge of security, including the sandbox model, the MIDP 2.0-trusted model, permissions and protection domains, and how MIDlet suites are signed and authenticated.

The sandbox model is about restricting the MIDlet suite execution environment. This is accomplished through a combination of techniques that include:

  • Classfile verification.
  • Protecting the core Java classes java.*, javax.microedition.* from being overridden.
  • Disallowing user-defined class-loaders; all class loading is performed by the system, and only system classes and classes from the MIDlet suite's JAR file can be loaded.
  • Disallowing direct access to external APIs and native code besides what is allowed by JTWI.

To enhance the security model, MIDP 2.0 introduced the concept of trusted MIDlet suites, permissions, and protection domains with the goal of restricting access to protected APIs and resources based on proper authorization.

A trusted MIDlet suite is one for which its origin and integrity can be verified; this is accomplished through code signing. MIDlet suite code signing is based on X.509 PKI public key digital certificates. Trusted MIDlets have access to all the APIs as specified by a protection domain.

An untrusted MIDlet suite is one whose origin and integrity cannot be verified, either because it is not signed, or because it has been changed without authorization. Note that a MIDP 1.0 MIDlet running on a MIDP 2.0 environment is considered untrusted because MIDP 1.0 MIDlets are not signed. Untrusted MIDlets still have access to most of the MIDP 2.0 APIs, including the MIDlet life cycle, record store, user interface, gaming and media control, HTTP, and the HTTPS APIs. Access to HTTPS requires explicit user confirmation. Allowing this kind of access provides backward compatibility with MIDP 1.0.

Permissions are used to restrict access to protected APIs and resources. Before a restricted API can be used, access must be authorized. Authorization can be explicit, not requiring user interaction, or it can be user-based, requiring user authorization. These authorization interaction types are defined in the device's security policy file. Permissions are requested through the JAD or manifest attributes MIDlet-Permissions and MIDlet-Permissions-Opt, using a case-sensitive, hierarchical name structure similar to Java package names; for example javax.microedition.io.Connector.sms.receive. Permissions are defined by the individual specifications; for example, MIDP 2.0 defines a set of permissions related to its APIs, as does WMA and other optional packages. The JTWI and MIDP 2.0's Recommended security policy for GSM/UMTS-compliant devices (see Resources) section contains more information on this.

A protection domain is the set of permissions that can be granted to MIDlet suites associated with a given domain. Protection domains also specify whether permissions are granted once (one-shot), on a session basis (session), or until the application is uninstalled (blanket). A MIDlet suite cannot belong to more than one protection domain.

I have now covered permissions and protection domains. Permissions describe "what" resources are to be authorized, and protection domains describe the mapping of "who has access to what resources." Two more things are needed for MIDlet suite authentication and authorization, though: the MIDlet suite's public key certificate and digital signature, which describes and authenticates the "who." MIDlet suite signing is illustrated in Figure 4.


Figure 4. Signing a MIDlet suite
Signing a MIDlet suite

Where:

  1. The X.509 Public Key certificates comprise the certificate path (the signer's public key) that is acquired from a Certificate Authority, and used to authenticate the signer.
  2. The JAR to sign and the JAD that contains the signature and certificate attributes MIDlet-Jar-RSA-SHA1 and MIDlet-Certificate-<n>-<m>. The certificate attribute is the certificate path minus the root certificate; the root certificate already resides in the device.
  3. The signer is the person responsible for generating the RSA-SHA1 JAR file signature and for adding this signature and associated certificate attributes and values to the JAD file.

After signing, a JAR file's contents can be authenticated and its integrity preserved. Any alteration to the JAR file results in its signature failing verification. This means that all the attributes defined in the JAR's manifest are protected by the signature; this is not the case for the attributes on the JAD, which are not protected.

There are strict rules related to the definition of attributes. If the MIDlet suite is trusted, attributes that appear both in the JAD and manifest must be equal; otherwise, the MIDlet suite won't install. This is to avoid manifest attributes from being overridden. For trusted MIDlet suites, manifest attributes take precedence over attributes in the JAD file, and retrieving an attribute using the MIDlet.getAppProperty() method returns the attribute from the manifest, and if not found there, then from the JAD, in that order. On the other hand, for untrusted MIDlet suites, retrieving an attribute that is found in both the JAD and the manifest results in the JAD attribute taking precedence and being returned; this is done to maintain backwards compatibility with MIDP 1.0.

During MIDlet suite installation, the following affects authentication:

  • If the MIDlet suite doesn't have a JAD file, it is not authenticated, and is installed as untrusted.
  • If the MIDlet suite has a JAD file but it doesn't have a MIDlet-Jar-RSA-SHA1 attribute, or, in other words, is not signed, the MIDlet suite is not authenticated, and is installed as untrusted.
  • If the JAD file has a MIDlet-Jar-RSA-SHA1 attribute, it is considered signed, and it is authenticated.

MIDlet suite authentication is about verifying the signature, so keep the following two rules in mind:

  • The public key certificate path is verified (root certificate, signatures, expiration). Failure to verify the certificate path results in the JAR not getting installed.
  • Verifying the signature is about using the public key from the above verified public key certificate, and using it to calculate a SHA-1 digest for the JAR file, which is compared against the value of the attribute MIDlet-Jar-RSA-SHA1. If they don't compare, the JAR is not installed.

After a MIDlet suite has been authenticated, it is considered trusted, and is bound to a protection domain as described in the security policy file and the suite's X.509 public key certificate, which identifies the MIDlet and its origin.

Except for signing the MIDlet suite, requesting permissions using the MIDlet-Permissions and MIDlet-Permissions-Opt attributes, and acting on security violations by catching SecurityException, the rest of the security items just described are transparent to the application.

Networking and the Generic Connection Framework

You must also have some knowledge of the Generic Connection Framework (GCF), including the connection types available in MIDP 2.0, as defined by the JWTI.

Introduced with CLDC 1.0, the GCF provides a lightweight and easy-to-use networking API that consists of a hierarchy of interfaces, a connection factory class, and an exception class; no network protocols are defined by the CLDC GCF.


Figure 5. The CLDC Generic Connection Framework
The CLDC Generic Connection Framework

Profiles such as MIDP, and optional packages such as WMA, extend the CLDC GCF by adding new network connection types and protocols. MIDP 1.0 introduced support for HTTP 1.1, and MIDP 2.0 added more enhancements, including support for serial (comm), sockets, UDP datagrams and secure connection-types, and the ability to automatically launch a MIDlet based on an inbound network connection.


Figure 6. The MIDP 2.0 Generic Connection Framework
The MIDP 2.0 Generic Connection Framework

GCF connections are created by calling the connection factory method javax.microedition.io.Connector.open(). The connection string URL argument to the connection factory specifies the connection type to create. The connection string URL has the following format:

{scheme}:[{target}][{params}]

Where:

  • scheme indicates the connection type; for example, comm, http, https, socket, sms, ssl, and datagram.
  • target indicates the local or remote connection end-point.
  • params are connection-specific parameters.

A connection URL for a client connection specifies a destination address, for example http://www.j2medeveloper.com:8080/rssfeed.xml. A connection URL for a server connection specifies a local address (no host, just a protocol-specific local address, typically a port number), for example sms://:9000.

The connection factory Connector.open() returns a connection type that you must cast appropriately; for example, if opening an HTTP connection you must cast the return value to HttpConnection. To close the connection, call the Connection.close() method.

HttpConnection is the only required connection type; all others are optional, but are very likely to be supported. Because WMA is a required optional package as defined by JTWI, MessageConnection is also required. Attempting to create an unsupported connection type results in a ConnectionNotFoundException.

Each network connection type has its own peculiarities. For example, HTTP is a request/response protocol, and utilizes headers that describe the HTTP content. Sockets are stream-based, communication is reliable, and typically over TCP. UDP datagrams are unreliable and each individual datagram must contain a destination address.

Data streams, such as InputStream and DataInputStream, and OutputStream and DataOutputStream are typically used to read or write from or to a network connection.

In addition to ConnectionNotFoundException, the following exceptions might be encountered when using the networking API: EOFException, IOException, InterruptedIOException, and SecurityException.

MIDlet activation using the PushRegistry

During the test, you are tested on your knowledge of the PushRegistry and how to activate MIDlets using timers and network activity.

The PushRegistry, introduced with MIDP 2.0, is a facility that allows an application to register with the AMS for timer and network-based activation. In other words, if the MIDlet is not running, the AMS can launch it based on a predetermined timer, or from an inbound network connection.

Applications can register for activation using static or dynamic registration. Static registration is accomplished by inserting MIDlet-Push-<n> entries in the JAD or manifest file. Dynamic registration is accomplished at run time by invoking the PushRegistry registerConnection() method. A MIDlet suite can register more than one PushRegistry activation. During registration, the following must be specified: 1) the connection type for the activation; 2) the class name of the MIDlet to launch; and 3) a filter used to restrict the senders that are allowed to launch the specified MIDlet; wildcard characters (* and ?) can be used in the filter. Not all connection types might be supported for push, and attempting to register an unsupported connection type results in ConnectionNotFoundException being thrown. Attempting to register a connection that is already registered, or a port that is already in use results in an IOException.. Attempting to statically register an unsupported connection type, or register a connection that is already registered, or a port that is already in use results in the MIDlet suite failing to install. PushRegistry supports network activation based on SMS/CBS, socket, and datagram network types.

Alarm or timer-based registration is accomplished by calling the registerAlarm() method and setting the time to a value some time in the future. Only one alarm per MIDlet in the MIDlet suite can be outstanding at any given time.

After registration, the AMS monitors the timer and inbound connections for MIDlets that are not running; MIDlets that are running don't need activation and can handle any inbound connections using the GCF. They can also use Timer and TimerTask to set up timers to schedule threads execution.

An application can determine if activation was due to an inbound network connection by calling the PushRegistry.listConnections() method with a parameter equal to true; passing true returns an array of connection URL strings that represent the connections that activated the MIDlet, and passing false returns an array that contains the complete list of all the registered push connections for the MIDlet suite.

When the application is destroyed, the AMS resumes monitoring for network activity and sends alarms as appropriate. But note that if the application closes the connection by calling Connection.close(), neither the AMS nor the application is able to monitor for inbound connections.

Managing data using the Record Store API

The exam tests your knowledge of the Record Management System (RMS), the life cycle of record stores, and how to manage records.

The RMS is a very basic record store in that RMS records are stored as byte arrays. A MIDlet suite can have multiple record stores, and the JTWI mandates the support for at least five record stores per MIDlet suite. JTWI also mandates that at least 30 KB of record store space, or the amount specified in attribute MIDlet-Data-Size, whichever is less, be supported per MIDlet suite.

The RecordStore class represents an RMS record store. One or more record stores can be opened or created by a MIDlet. Each record store must be uniquely named using a case-sensitive name that cannot exceed 32 characters in length. The record store can be removed at any time by the MIDlet, and is automatically removed by the AMS when the MIDlet suite is removed. The contents of the record store remain in the store even across MIDlet invocations. When updating a MIDlet suite, its record store's contents are retained only if the new MIDlet suite is considered trusted and its source is the same as the one being replaced.

As previously mentioned, RMS stores information as byte arrays (byte[]). The application is responsible for properly formatting the byte array record as appropriate. For example, you might have a class that needs to be stored. In this case, you are responsible for serializing its contents into a byte array. This is accomplished by using data streams such as ByteArrayOutputStream and DataOutputStream to convert to a byte array that can be stored, and ByteArrayInputStream and DataInputStream to convert from a byte array that can be read.

Records are uniquely identified by an int value. This record ID, which is unique for the life of the record store, is returned when a record is added. The first record created is always record ID 1. The record ID is used to retrieve, modify, or remove the record.

RMS provides a number of methods for managing records stores, for example:

  • To create and open a record store use openRecordStore().
  • To remove a record store use deleteRecordStore().
  • To close a record store use closeRecordStore().
  • To enumerate records in a record store use enumerateRecords().
  • To set a listener to monitor when a record has been added, changed, or deleted use addRecordListener().
  • Other methods provide access to the record store version, its size, and number of records.

RMS provides methods for managing records, such as:

  • To add a new record use addRecord().
  • To retrieve a record use getRecord().
  • To modify a record use setRecord().
  • To remove a record use deleteRecord().
  • To get a record's size use getRecordSize().

RMS protects the record store to prevent data corruption across multiple record store operations; RMS operations are serialized, blocking or synchronous, and atomic. Note that the record store API is not synchronized; if your application is multithreaded, with multiple threads accessing the record store, you must synchronize access to the record store to prevent data loss or overwriting records.

To traverse the records on a record store, a record enumeration, or RecordEnumeration, is used. The record enumeration can be filtered using a RecordFilter and ordered using a RecordComparator.

Starting with MIDP 2.0, record stores can be shared across MIDlet suites, even untrusted MIDlets.

There are a number of exceptions that might be thrown during RMS operations, including RecordStoreException, RecordStoreNotOpenException, RecordStoreFullException, SecurityException, InvalidRecordIDException, and ArrayIndexOutOfBoundsException.

The MIDP user interface API

Additionally, the exam test your knowledge of MIDP 2.0 user interface APIs, including their class structure, restrictions, and the high- and low-level APIs.

JTWI mandates the following minimum screen characteristics:

  • Screen size of 125x125 pixels
  • Color depth of 4096 colors (12 bits)
  • Pixel aspect ratio of 1:1

The MIDP user interface API, LCDUI, consists of a low-level 2D-graphical API, and a high-level API that allows developers to write portable, device-independent screens.

The Display class is the display manager. A MIDlet needs a reference to the display manager to manage screens. A reference to Display is obtained by calling the Display.getDisplay() method, usually when the MIDlet starts running. The Display class manages objects of type Displayable, which are objects that can be displayed on the screen. The Display class also provides methods to discover information such as the number of supported colors, the alpha transparency level, and helper methods to make the device vibrate, to flash the backlight, and to set the active or visible Displayable screen. To make a displayable active, the Display.setCurrent() method is used, passing as argument the Displayable object to make active. Note that only one Displayable can be active at a time.

The abstract class Displayable provides common attributes such as a title, ticker-tape, and high-level user interface input commands that are typically represented as soft keys. Examples of these commands include BACK, CANCEL, EXIT, HELP, OK, and application-defined screen-specific SCREEN commands. Subclasses of Displayable provide the high- and low-level screen types, as illustrated in Figure 7.


Figure 7. MIDP 2.0 top-level user interface classes
MIDP 2.0 top-level user interface classes

The Screen subclass represents a high-level, device-independent displayable, while Canvas represents a low-level, graphically based displayable.

The high-level user interface API defines a set of Screen types or predefined widgets, such as alarm dialogs, lists and choices, sliders, and forms. Because the goal of this high-level API is to provide a device-independent set of widgets, operations such as painting and key input are handled by the implementation; this means the developer has no control on how these are painted, how key-input is handled, how the screen is navigated, or how content is scrolled. Figure 8 summarizes the high-level UI API class structure that includes the Screen and its subclasses, and the Items that can be inserted into a Form.


Figure 8. MIDP 2.0 high-level API class structure
MIDP 2.0 high-level API class structure

The widgets List and TextBoxes provide simple-to-use full screens to display a list of items and a text edit box respectively. Alert is a special type of fullscreen that can be used as a dialog, to inform the user about application-specific information, warnings, errors, and other conditions. An Alert can contain a text string and an image, and can show data for a certain period of time before automatically proceeding to the next specified Displayable. A Form is a more complex and rich type of fullscreen that serves as a container of Items such as a date fields, choice lists, editable text boxes, images, and support for custom items. A custom item, which is new in MIDP 2.0, is a very powerful widget that brings the power of low-level graphical user interfaces into the high-level Form.

The low-level API consists of the set of classes for basic 2D graphics. Figure 9 summarizes the low-level UI API class structure.


Figure 9. MIDP 2.0 low-level API class structure
MIDP 2.0 low-level API class structure

The low-level Canvas provides methods for drawing lines, boxes, circles, and other graphic primitives. Canvas provides total control of the screen. In fact, the application is responsible for how and when painting is done, how and when low-level game keys or pointer input is handled, managing fonts, how the screen is navigated, and how the content is scrolled. Because Canvas is also a Displayable, it can also define the application-specific commands, or soft keys.

When using the low-level API it is important to query the system and screen characteristics to ensure your graphical screens are portable. For example, you can obtain the screen width in pixels by calling Canvas.getWidth(), get the screen's height in pixels by calling Canvas.getHeight(), discover font sizes in pixels by using the Font class, discover the number of supported colors and the alpha transparency level by using the Display class, and discover image sizes using the Image class. The bottom lines is you must never hardcode values in your application. The canvas coordinate (0, 0) is the upper-left corner of the display.

The MIDP game API

The exam tests your knowledge of MIDP 2.0 game API, its class structure, and how to use it.

The game API was introduced with MIDP 2.0. This API extends the low-level LCDUI API with game-specific elements. Its class structure is summarized in Figure 10.


Figure 10. MIDP 2.0 game API class structure
MIDP 2.0 game API class structure

GameCanvas is a subclass of Canvas, with enhanced gaming characteristics such hardware-assisted graphical operations, a dedicated off-screen buffer, animation, additional game key actions, and an efficient way to retrieve the game key states without having to query for each key. The Layer, Sprite, and TiledLayer represent visual elements of a game. LayerManager manages a series of layers. A TiledLayer is typically used to display background, while Sprite displays moving objects.

Because the GameCanvas subclasses Canvas, the Canvas primitive graphic operations can be used on a GameCanvas.


Short messaging with the Wireless Messaging API

The exam tests your knowledge of short messaging using the Wireless Messaging API 1.1 (JSR 120) optional package. You can find more information on this in Resources.

The presence of WMA is required by JTWI. WMA extends the CLDC Generic Connection Framework and defines short message types and a message listener. Figure 11 summarizes the WMA class structure.


Figure 11. The GCF and Wireless Messaging API class structure
The GCF and Wireless Messaging API class structure

MessageConnection is a subinterface of the GCF Connection interface, and it provides methods to create messages, methods to send and receive messages, and to set the connection's message listener. Message is the base interface that represents a generic short message. The TextMessage subinterface represents a short text message with methods to manipulate text data, while the BinaryMessage subinterface represents a short binary message with methods to manipulate binary data.

The typical maximum message size is 160 (7-bits) text characters in length, or 140 (8-bits) binary bytes. If using USC-2 (2-byte) characters, the maximum size is 70 characters. The underlying implementation determines the character encoding used. If port numbers are used for message addressing, the maximum message size is reduced.

WMA supports multisegment messages, with at least 3 segments per message, allowing for larger messages. Message segmentation and reassembly is taken care of by the implementation. In order to maintain application portability, your application should not use more than three segments per message. You can query how many SMS segments a given message would require by calling the MessageConnection.numberOfSegments() method. Attempting to send a message that is larger than the allowed number of segments results in an IOException.

As with all GCF connections, a MessageConnection is created by calling the connection factory Connector.open() method, passing as argument the connection URL string. A connection URL for a client connection specifies a destination address, while a connection URL for a server connection specifies a local address (no host, just a protocol-specific local address, typically a port number); for example:

  • Client: (MessageConnection)Connector.open("sms://+15121234567:7000");
  • Server: (MessageConnection)Connector.open("sms://:8000");

Valid WMA connection URL schemes are:

  • sms: indicates a bidirectional Short Messaging System and supports both client and server connections.
  • cbs: indicates the broadcast, receive-only Cell Broadcast Short Message. Attempting to send on a cbs connection results in an IOException.

After the connection has been established, the application can wait/block for messages by calling the MessageConnection.receive() method. An alternative approach is to use asynchronous notification of incoming messages by using a message listener. To use asynchronous notifications, the application must implement the MessageListener interface and register the listener with a message connection by calling the MessageConnection.setMessageListener() method; for each incoming message, the implementation calls the MessageListener.notifyIncomingMessage() method.

WMA can be used with PushRegistry to activate the MIDlet when an incoming SMS message has been received. If the MIDlet is not active, the AMS buffers the message. After the MIDlet is launched, the AMS passes any buffered messages to the appropriate applications. See the PushRegistry section for more information.

WMA defines the system property wireless.messaging.sms.smsc that describes the Short Message Service Center (SMSC) address used for sending the messages. Recall that system properties are retrieved by calling the System.getProperty() method.

When using WMA, the following exceptions might be thrown: ConnectionNotFoundException, IllegalArgumentException, InterruptedIOException, IOException, NullPointerException, and SecurityException. See the WMA 1.1 specification (see Resources) for more information.


Media control with the Media API

The exam tests your knowledge of the media APIs, the MIDP 2.0 Media API, and the Mobile Media API 1.1 (JSR 135) optional package (see Resources for more information), as well as their relationships, concepts, and how to control media.

There are two sets of media APIs: the MIDP 2.0 Media API and the Mobile Media API optional package. These media APIs provide multimedia processing for devices with sound and video capabilities, and the relationship between the two is illustrated in Figure 12.


Figure 12: Relationship between the MIDP 2.0 Media API and MMAPI
Relationship between the MIDP 2.0 Media API and MMAPI

The MIDP 2.0 Media API is a subset of the MMAPI 1.1. Both APIs are based on the same basic principles and concepts. Because JTWI specifies that the MMAPI is a conditionally required specification, meaning that it might not be available, you must understand the differences between the subset and the full MMAPI.

The main elements of the media APIs are summarized in Figure 13.


Figure 13: Main elements of the Media API
Main Elements of the Media API

A Manager provides access to resources such as Players. The manager also provides a simple tone generator, the playTone() method. Additionally, Manager provides helper methods to query the supported media content types and protocols.

A Player has one or more media-specific Controls, and might have a DataSource. A DataSource provides custom delivery of media while hiding the details of how data is read. DataSource is supported in the MMAPI and is not supported in MIDP 2.0 media.

Using a Manager, the J2ME application creates a Player, through which it uses Controls to control media. This is illustrated in Figure 14.


Figure 14: Using the Media API
Using the Media API

A Player is created through Manager using: 1) a locator that describes the media content to play; 2) by specifying an InputStream and media-type; or 3) by specifying a DataSource. As previously mentioned, DataSource is not supported in MIDP 2.0. The locator is a URL string with the following format.

<scheme>:<scheme-specific-part>

scheme identifies the protocol name used to deliver the data; for example, http://server/content to serve the content from a server, or Manager.TONE_DEVICE_LOCATOR if using the local tone device. If creating the player from an InputStream, the input stream could come, for example, from a resource file in the MIDlet suite JAR that is accessed by calling the method getResourceAsStream(), or might come from an HttpConnection. If creating the player from a DataSource, it must be created beforehand by specifying a locator.

The Player provides playback of content. The playback operation can be a simple one, in which the content is played without controls, or else programmatically controlled. The former is very simple to use, but doesn't provide any control, whereas the latter provides total control but requires following a specific playback life cycle and its five states: UNREALIZED, REALIZED, PREFETCHED, STARTED, and CLOSED. The media API supports asynchronous Player events through a PlayerListener that the application must implement and register with a Player. These asynchronous events allow the application to track the state of a player, such as if the player has started, is stopped, has encountered an error, or the end-of-media has been reached.

A Control is a media-specific control for such things as MIDI playback, volume, JPEG video snapshots, or tone sequences. Figure 15 illustrates the MIDP 2.0 and MMAPI controls.


Figure 15. Media controls
Media controls

Note that while the MMAPI supports both audio and video controls, the MIDP 2.0 media API is limited to audio only.

To synchronize the media playback from multiple players, the MMAPI provides TimeBase, a time source with microsecond resolution. TimeBase is not supported in MIDP 2.0.

The media API provides system attributes that can be queried by calling System.getProperty(), for example:

  • supports.mixing to discover if mixing is supported
  • supports.audio.capture to discover if audio capture is supported
  • supports.video.capture to discover if video capture is supported
  • supports.recording to discover if recording is supported
  • audio.encodings to retrieve the supported audio encodings
  • video.encodings to retrieve the supported video encodings

When using the media API, the application must handle MediaException whenever it is encountered. Refer to the MMAPI 1.1 specification (see Resources) for more information.


In conclusion

After reading this article, you should have a better appreciation for the topics you'll encounter in the SCMAD certification exam. There is quite a bit of material to master, and this article provided just a peek into it, but this should not discourage you! By familiarizing yourself with the specifications covered here and writing some code examples yourself, you're well on your way with your preparation.


Resources

About the author

C. Enrique Ortiz co-designed the Sun Microsystems' Mobile Java Developer Certification Exam, and is an active participant in the wireless Java community and in various J2ME expert groups. He is a software architect and developer, and a wireless mobility technologist and writer who has authored and co-authored many publications. Enrique holds a B.S. in Computer Science from the University of Puerto Rico and has more than 15 years of software engineering, product development, and management experience.

Comments



Trademarks

static.content.url=/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=47219
ArticleTitle=Preparing for the Mobile Application Developer Certification
publish-date=02152005
author1-email=eortiz@j2medeveloper.com
author1-email-cc=