Sie sind auf Seite 1von 6

JSR 211

A first glimpse on the brand new J2ME API for


content handling
Published for public review in July, the JSR 211 - Content Handler API (also known as CHAPI)
stands out as one of the most useful and innovative new APIs on the J2ME universe. In short, the
API defines a communication model between applications (either Java/J2Me or native applications),
in a way that developer can specify MIDlets as the content handlers for one or more specific file
types.

Although this article focuses on the JSR 211 implementation on the MIDP platform, the API is
designed for use on both MIDP and PBP (Personal Basis Profile) compliant devices. On this
second case, the usage of the API should be possible via an Xlet or any properly packaged
program. Examples on this scenario won’t be covered on this article.

All the ideas behind the JSR 211 are based on the Content Handler concept. According to this
execution model, a given MIDlet can, for instance, register itself into the device’s operational
system to manipulate files belonging to the image/png MIME-type, and determinate that its sole
responsibility is to visualize this kind of file. Once this registration is done, the MIDlet becomes the
registered application which “knows” how to show visualizations of the referred Content Type, and
from this moment onwards, any requests for visualization of a png file would automatically activate
the MIDlet (either requested by Java applications or not). The picture below, borrowed from the
CHAPI specification, shows where the API implementation fits on the J2ME architecture: although
it presents a new set of classes for developers to use on their Java Applications, the major changes
are focused on the virtual machine’s AMS (Application Management System), which is responsible
for the interactions between the MIDlets and the underlying operating system.

The invocation concept of the content handlers is based on URIs, in a way that the MIDlet that
invokes a content handler doesn’t specify which application is being called – it only informs the
content which will be handled (indicated via its URI, in a similar way to the platformRequest
method on the MIDlet class), the operation to be executed (editing, saving, creating, etc), and any
other parameters which might be needed for execution.
In specific cases where more than one Content Handler is registered for a specific file type (for
instance, when there are two MP3 players on the device), the invoking application can indicate
which application to open by specifying its ID. The execution of chained (sequential) content
handlers is also a feature predicted by the API, and would allow more than one application to
process the content in sequence, each one handing the execution to the next.
The specification states two possible execution modes for the content handling process, depending
on the device’s multitasking capabilities. In devices where the parallel execution of applications
(multitasking) is possible, the API dictates that the content handler can be executed in a higher
priority thread, and then send an answer back to the invoker application (which is once again
brought to the foreground) without any need to finalize the invoker before the content is handled.
The usage priority for the display is also affected by this execution model: the API specifies that the
requests for screen drawing (such as callings to paint() method or access to the Display object)
made by the application which is currently in background (e.g. the invoker, at the time the request is
being handled) have lower priority than calls made by the application on foreground.
On devices where only one application can be executed at a time, the invoker must be finished
before the content handler executes, and the content handler has to finish before the invoker can get
a response back.

Getting started: the javax.microedition.content package


The CHAPI is a small API: composed by seven classes (including a general usage exception
class), it includes all the necessary mechanisms for invoking a content handler and getting a
response back, registering and unregistering a content handler and looking up for installed handlers.
The package classes follow:

• Registry - Responsible for invoking, registering and unregistering content handlers.


• ContentHandler - Provides details on the specific content handler: Id, authorization and access
information, application name, allowed content types, etc.
• Invocation - Contains a list of parameters, accessible to the content handler and the callee during a
requisition.
• ContentListener - Listener responsible for assynchronous notifications on pending requests and
responses.
• ContentHandlerServer - Allows the processing of requests and their finalization.
• ActionNameMap - Maps actions to descriptive action names.
• ContentHandlerException - Generic error class for content handling.

Content Handling in a Nutshell


Step 1: Invoking a Content Handler
The invocation of a Content Handler is a simple task, as exemplified below. In the example, the
application requests the content manipulator for the vcard file type to be activated using an
Invocation object instance, specifying the opening action (ContentHandler.ACTION_OPEN) and
providing some additional parameters (arguments), which can be used by the content handler to
perform business-specific operations. It is important to notice that the only connection model which
is mandatorily implemented on every MIDP 2.0 compliant device is the HttpConnection. Even
though, it is possible to use any other protocols on devices which have specific stack
implementations, due to the Generic Connection Framework model. A device which implements the
JSR 75 (and thus supports a filesystem) should, for instance, request a content handler for a file
(e.g., “file:///MMC:/mypicture.gif”) when instantiating the Invocation object.
// Invoke based on a URL
try {
String url = “http://host/jones.vcard”;
Invocation invoc = new Invocation(url);
invoc.setAction(ContentHandler.ACTION_OPEN);
invoc.setArgs(new String[] {"debug"});
if (Registry.invoke(invoc, this)) {
// App must exit before invoked application can run
notifyDestroyed(); // inform the application manager
} else {
// Application does not need to exit

Invocation ret = Registry.getResponse(this, 1000);


// handle the returned invocation result here!
Alert alert = new Alert(“”, “Content handling status: ” + ret.getStatus() + " for content
" + ret.getUrl(),

null, null);
display.setCurrent(alert);
}
} catch (IOException ex) {
Alert alert = new Alert(“”, “Could not go there”, null, null);
display.setCurrent(alert);
}

The invocation of a handler is made via the Registry.invoke() method. This method returns a
boolean value, which indicates if the invoker must be closed before the content handling takes
place.
Our example also includes the handling for an expected response: by calling the
Registry.getResponse() method, it is possible to recover the Invocation object containing the result
of the processing made by the Content Handler. All the Invocation attributes (action, args, url,
status, etc.) can be freely accessed, making the response handling a rather simple procedure as well.

Step 2: Handling a Request


The handling of a requisition is also a simple task. The example below shows an application which
is able to handle our requisition and show the result to the user until she presses any key and closes
the content handler.
public class VCardViewer extends MIDlet
implements ContentListener, CommandListener {
Invocation invoc;
ContentHandler handler;

public VCardViewer() {
// Register the listener to be notified of new requests
handler = Registry.forClass(this.getClass().getName());
handler.setListener(this);
}

// Process a queued Invocation.


public void invocationNotify() {
// Dequeue the next invocation
invoc = handler.getRequest(0L);
if (invoc!= null) {
// Display the content of the VCard
displayVCard(invoc);
}
}

public void commandAction(Command c, Displayable s) {


if (c == okCommand) {
if (invoc!= null) {
if (handler.finish(invoc, Invocation.OK)) {
notifyDestroyed(); // inform the application manager
}
invoc = null;
}
}
}

void displayVCard(Invocation invoc) throws Exception {


HttpConnection conn = (HttpConnection)invoc.open(false);
VCard vcard = parseVCard(conn.getInputStream());
...
// Display the content based on the action
String action = invoc.getAction();
if (ContentHandler.ACTION_OPEN.equals(action)) {
showView(vcard);
}
if (action.getArgs()!= null && action.getArgs()[0].equals("debug")) {
System.out.println("Application on debug mode!");
}
}
}

During the example initialization, the call to the Registry.forClass() method returns an instance of
the ContentHandler object associated with the MIDlet (this instance is associated when the MIDlet
is registered as a Content Handler. We will talk about this procedure later on this article). Using this
instance, we can access the pending requisitions and process them as desired. The MIDlet is
notified about pending requisitions through the invocationNotify() method from the ContentListener
class (following the request-response model commonly adopted on other APIs, such as the Wireless
Messaging API), and can retrieve the invocation data by calling the getRequest() method.
Once the Invocation object is accessible, the content can be retrieved by using the Generic
Connection Framework, and accessed as a streaming of data. The Invocation object also grants
access to all the attributes which were configured during the instantiation of the Invocation: action,
arguments, status, etc.

Step 3: Getting the response back


Once the user decides to finish the content handling (in our example, when the ‘ok’ softkey is
pressed and the commandAction() method is executed), the ContentHandler.finish() method must be
invoked. The invoking applications is then notified of the completion and can return to the main
execution thread (if it is active). The behavior of the finish() method is similar to the invoke():
depending on the implementation, the content handler must finalize before the callee can return to
execution or not.

Discovering the Registered Handlers


Several methods on the Registry class allow the developer to discover which are the handlers
responsible for specific content types. Among the methods, it is possible to know which are the
existing registered content handlers for given actions (delete, open, rename, etc), for a given file
suffix (.png, .vcard, .mid, etc), for a given MIME-type (text/html, image/gif, etc) and finally, locate
the content handlers identified by a specific ID.

Registering a Content Handler


In order to our VCardViewer MIDlet to be recognized as a content handler, we have to register it
along with the AMS. The most common approach is the static registration: as long as the MIDlet
declares its content handling attributes in the .jad descriptor, it is automatically registered during
installation on the device. The sample code below shows the descriptor for our example application.
Since the content handling is a sensitive system resource and prone to missuse, the declaration of MIDlets as
Content Handler requires that these should be signed/authorized by the user for them to work. The
specification states that MIDlets must be into the javax.microedition.content.ContentHandler security
domain to properly work as content handlers.

MIDlet-1: VCardViewer, /icons/vcard.png, example.VCardViewer


MicroEdition-Handler-1: example.VCardViewer, text/vcard, open, .vcard
MicroEdition-Handler-1-en-US: View
MicroEdition-Handler-1-br-PT: Visualizar
MicroEdition-Handler-2: example.VCardEditor, text/vcard, edit, .vcard
MicroEdition-Handler-2-en-US: Edit
MicroEdition-Handler-2-br-PT: Editar
MicroEdition-Handler-ID: http://jsr-211.java.net/vcardhandler
MIDlet-Jar-Size: 2751
MIDlet-Jar-URL: http://java.net/example/jarFileName.jar
MIDlet-Name: Example Content Handlers
MIDlet-Vendor: Sun Microsystems, Inc.
MIDlet-Version: 1.0
MicroEdition-Configuration: CLDC-1.0
MicroEdition-Profile: MIDP-2.0
MIDlet-permissions: javax.microedition.content.ContentHandler

Among the attributes on this descriptor, only the ones starting by MicroEdition-Handler preffix
really deserve a detailed explanation in our context:
MicroEdition-Handler-<number>: these attributes describe the handlers included in the Midlet
Suite. The arguments are the name of the MIDlet which is responsible to handle the content (in our
case, VcardViewer and VCardEditor), the supported MIME-types, the supported operations (only
open and edit, in our case) and the suffix of the supported files.
MicroEdition-Handler-<number>-<locale>: stores descriptive names of the actions. These names
can be retrieved by applications using the ActionNameMap class, and are usually useful for
exhibition on the user interface. The locale suffix allows them to be internationalized to different
languages (en-US, br-PT, etc)
MicroEdition-Handler-ID: The unique identifier of this content handler package on the device.
This identifier doesn’t need to be supplied, since it can be generated by the underlying
implementation.

Although not as recommended as the static registration, the dynamic registration of MIDlets is also
possible. The sample code below registers a MIDlet as the content handler for image/png files and
defines that the MIDlet will be responsible for handling opening requests
(ContentHandler.ACTION_OPEN) for this kind of file. The registration is made via the
Registry.register() method call. Complementarily, the Registry.unregister() method allows the
unregistration of an application previously defined as a content handler. Content Handlers are also
unregistered automatically when their corresponding MIDlets are removed (uninstalled) from the
device.
try {
// Create a content handler instance for our Generic PNG Handler
String[] chTypes = { “image/png” };
String[] chSuffixes = { “.png” };
String[] chActions = { ContentHandler.ACTION_OPEN };
String chClassname = “example.content.PNGHandler”;
ContentHandler handler =
Registry.register(chClassname, chTypes, chSuffixes, chActions);
} catch (ContentHandlerException ex) {
// Handle exception
}

Conclusions
The CHAPI is an optional package, and the final specification will be available on August. Due to
it’s extreme usefulness and the new level of interaction it brings to the J2ME world, it is possible
that many manufactures decide to implement this JSR on their MIDP 2.0 compliant devices in a
short period of time. We really hope so!

Links
JSR 211 – Content Handler API - http://www.jcp.org/en/jsr/detail?id=211
Official JSR page, where the public specification and latest Javadoc can be found.

Herval Freire (herval@sollipsis.com) is a Sun Certified Java Programmer (SCJP), Web Components
Developer (SCWCD) and Micro Application Developer (SCMAD), and works as a senior consultant on
wireless and mobility projects.

Das könnte Ihnen auch gefallen