Just An Application

June 23, 2009

What’s New In MIDP 3.0 ? Part 18: LCDUI – Displays

Filed under: Java, JME, LCDUI, MIDlets, MIDP, MIDP3, MIDP3API, MIDP3LCDUI — Tags: , , , , , , , — Simon Lewis @ 9:28 am

1. The Display Model

  • A device has one or more physical displays.

  • Each physical display may support sharable and non-sharable functionality.

  • The supported functionality may differ between physical displays.

  • A Display gives a MIDlet access to a fixed set of the functionality of a corresponding physical display.

  • A MIDlet will always have access to a primary display corresponding to the main physical display of the device.

  • If a device has additional physical displays a MIDlet will have access to corresponding secondary Displays.

  • If a physical display has two or more operating modes each with a discrete set of functionality a MIDlet will have access to those
    modes via two or more Displays.

2. Display Characteristics

2.1 Getting The Display’s Height

A Display’s height in pixels can be obtained by calling its

    public int getHeight()

method.

The value returned is the maximum height available for the display of a Displayable including its Title, Ticker, Commands and Menus, if present.

2.2 Getting The Display’s Width

A Display’s width in pixels can be obtained by calling its

    public int getWidth()

method.

The value returned is the maximum width available for the display of a Displayable including its Title, Ticker, Commands and Menus, if present.

2.3 Getting The Display’s Dot Pitch

A Display’s dot pitch can be obtained by calling its

    public int getDotPitch()

method.

The value returned is the distance between adjacent pixels in micrometers (1 x 10-6m).

2.4 Does The Display Support Pointer Events ?

Whether or not a Display supports Pointer events can be determined by calling its

    public boolean hasPointerEvents()

method.

The method returns true if the Display is capable of reporting Pointer pressed and released events.

Notes

  1. This method effectively supercedes the Canvas.hasPointerEvents() method. Whether Pointer events are supported by a Canvas is actually dependent upon the Display on which the Canvas is currently visible.
  2. It is not clear why, other than for convenience, this functionality is not implemented using the capabilites mechanism.

2.5 Does The Display Support Pointer Motion Events ?

Whether or not a Display supports Pointer Motion events can be determined by calling its

    public boolean hasPointerMotionEvents()

method.

The method returns true if the Display is capable of reporting Pointer motion eventst.

Note

  1. This method effectively supercedes the Canvas.hasPointerMotionEvents() method. Whether Pointer motion events are supported by a Canvas is actually dependent upon the Display on which the Canvas is
    currently visible.
  2. It is not clear why, other than for convenience, this functionality is not implemented using the capabilites mechanism.

2.6 Is The Display Built-in ?

Whether or not the corresponding physical of a Display is built-in can be determined by calling its

    public boolean isBuiltIn()

method.

The method returns true if the corresponding physical display is built-in, that is, if it is an integral part of the device. If it is then the corresponding Display will never become unusable as the result of the removal of the corresponding physical display.

3. Display Capabilities

The functionality supported by a given Display is specified at runtime using capabilities, where a capability typically represents a discrete LCDUI feature.

The following capabilities are defined as constants in the Display class.

  • SUPPORTS_ALERTS
  • SUPPORTS_COMMANDS
  • SUPPORTS_FILESELECTORS
  • SUPPORTS_FORMS
  • SUPPORTS_IDLEITEM
  • SUPPORTS_INPUT_EVENTS
  • SUPPORTS_LISTS
  • SUPPORTS_MENUS
  • SUPPORTS_ORIENTATION_LANDSCAPE
  • SUPPORTS_ORIENTATION_LANDSCAPE180
  • SUPPORTS_ORIENTATION_PORTRAIT
  • SUPPORTS_ORIENTATION_PORTRAIT180
  • SUPPORTS_TABBEDPANES
  • SUPPORTS_TEXTBOXES
  • SUPPORTS_TICKER
  • SUPPORTS_TITLE

The constants are bit-flags and can be combined using bit-wise OR.

A MIDlet’s primary Display will support all LCDUI features but a secondary Display may not.

All Displays provides basic Canvas support.

The capabilities of a Display are fixed.

3.1 Getting A Display’s Capabilities

A Display’s capabilities can be obtained using its

 public int getCapabilities()

method.

The return value will either be the bit-wise OR’ed combination of the supported capabilities, or 0 indicating that the Display only provides basic Canvas support.

3.2 DisplayCapabilityException

A DisplayCapabilityException is thrown when an attempt is made to perform an operation which directly or indirectly involves a Display which does not support the functionality required for the operation. For example, passing an instance of Form to the setCurrent() method of a Display which does not support Forms.

4. Display State

A Display can be in one of three states

  • Foreground,
  • Background, or
  • Visible

depending upon its current level of access to the functionality of the corresponding physical display.

4.1 Foreground

If a Display is in the Foreground state then it currently has exclusive access to all non-sharable functionality of the corresponding physical display, and first-call on any sharable functionality.

4.2 Background

If a Display is in the Background state then it currently has no access to the functionality of the corresponding physical display.

4.3 Visible

If a Display is in the Visible state then it has access to at least one pixel of the corresponding physical display, but it has no access to any of the non-sharable functionality.

4.4 Runtime Constants

The possible display states are represented by the following constants defined in the Display class

  • STATE_BACKGROUND
  • STATE_FOREGROUND
  • STATE_VISIBLE

4.5 Getting The Current Display State

The current state of the Display can be obtained using the Display’s

    public int getDisplayState()

method which will return one of the constants listed above.

5. Hardware State

The hardware state of a Display is equivalent to the state of the corresponding physical display.
The physical display may be

  • Enabled,
  • Disabled, or
  • Absent

The hardware state of a MIDlet’s primary display will never be Absent.

5.1 Enabled

If the hardware state of a Display is Enabled then the functionality of the corresponding physical display is available to the Display.

5.2 Disabled

If the hardware state of a Display is Disabled then the functionality of the corresponding physical display is not available to the Display.

5.3 Absent

If the hardware state of a Display is Absent then the corresponding physical display is no longer available and the Display itself is no longer usable.

5.4 Runtime Constants

The possible hardware states are represented by the following constants defined in the Display class

  • DISPLAY_HARDWARE_ABSENT
  • DISPLAY_HARDWARE_DISABLED
  • DISPLAY_HARDWARE_ENABLED

5.5 Getting The Current Hardware State

The current hardware state of a given Display can be obtained used the Display’s

    public int getHardwareState()

method which will return one of the constants listed above.

6. Activity Mode

The activity mode of a Display may be either Normal or Active.

If a Display is in the Foreground state and its activity mode is Normal then the corresponding physical display may enter a reduced functionality power-saving state if the current power management policies of the device allow it.

If a Display is in the Foreground state and its activity mode is Active then the corresponding physical display should remain in a fully functional state.

If a Display in the Foreground state changes its activity mode from Normal to Active and the corresponding physical display is in a power-saving state it should return to a fully functional state.

The possible activity modes are represented by the following constants defined in the Display class.

  • MODE_ACTIVE
  • MODE_NORMAL

6.1 Getting The Current Activity Mode

The current activity mode of a Display can be obtained by calling it’s

    public int getActivityMode()

method which will return one of the runtime constants listed above.

6.2 Setting The Current Activity Mode

The current activity mode of a Display can be set by calling it’s

    public void setActivityMode(int mode)

method.

The mode argument must be one of the constants listed above.

7. Display Orientation

A Display may support more than one orientation.

Possible orientations are

Landscape Display’s width is greater than its height
Landscape 180 Landscape with content rotated through 180 degrees
Portrait Display’s height is greater than its width
Portrait 180 Portrait with content rotated through 180 degrees

The orientations supported by a Display can be determined by calling its getCapabilities() method.

7.1 Runtime Constants

The possible orientatations are represented by the following constants defined in the Display class

  • ORIENTATION_LANDSCAPE
  • ORIENTATION_LANDSCAPE180
  • ORIENTATION_PORTRAIT
  • ORIENTATION_PORTRAIT180

7.2 Getting The Orientation

The current orientation of the Display can be obtained by calling its

    public int getOrientation()

method which will return one of the constants listed above.

7.3 Setting The Preferred Orientation

The preferred orientation of a Display can be set using its

    public void setPreferredOrientation(int orientation)

method where orientation must be one of the constants listed above.

Note

It is not clear from the specification exactly what setPreferredOrientation() does. It states

This call may not have an effect on the actual orientation of the display if the specified orientation is not supported on the device.

It then goes on to say

The application may use getOrientation() to detect the actual orientation of the display after this call.

which would seem to imply that it is not guaranteed to do anything even if the specified orientation is supported by the Display.

More generally it is not clear what it means for a Display to support a given orientation. One possible interpretation is that if a Display supports more than one orientation, then, if the orientation of the Display changes it will automatically re-render all visible UI elements appropriately. This would seem to make sense as there is no API by which a MIDlet could achieve the same effect. Other aspects of the UI such as the size of the UI elements are potentially under the control of the MIDlet and are presumably, therefore, its responsibility.

8. Display Events

A MIDlet can listen for the addition of secondary Displays, and for changes in the

  • display state
  • hardware state
  • orientation
  • size

of individual Displays using an instance of the DisplayListener interface.

All Display events are serialized with respect to other LCDUI events.

Note

An orientation change may also result in a size change, but the specification does not explicitly state that the resulting events must occur in a particular order.

8.1 Adding A DisplayListener

A MIDlet can begin listening by using the Display method

    public static void addDisplayListener(DisplayListener l)

to add a DisplayListener.

8.2 Removing A DisplayListener

A MIDlet can stop listening using the Display method

    public static void removeDisplayListener(DisplayListener l)

to remove a DisplayListener added previously.

8.3 DisplayListener

Events are reported to a DisplayListener using event specific methods as follows.

8.3.1 Addition

The addition of secondary display is reported via the

    public void displayAdded(Display d)

method.

8.3.2 State Changes

Changes to the state of a Display are reported via the

    public void displayStateChanged(Display d, int newState)

method.

The newState argument will be one of the Display state runtime constants.

8.3.3 Hardware State Changes

Changes to the hardware state of a Display are reported via the

    public void hardwareStateChanged(Display d, int newState)

method.

The newState argument will be one of the Hardware state runtime constants.

8.3.4 Orientation Changes

Changes to the orientation of a Display are reported via the

     public void void orientationChanged(Display d, int newOrientation)

method.

The newOrientation argument will be one of the Orientation runtime constants.

8.3.5 Size Changes

Changes to the size of a Display are reported via the

    void sizeChanged(Display d, int w, int h)

method.

The arguments w and h are the new width and height of the Display respectively.

9. Getting Displays

9.1 Getting The Primary Display

The existing Display method

    public static Display getDisplay(MIDlet m)

will return the primary Display for the given MIDlet.

9.2 Getting Displays With Specific Capabilities

The new Display method

    public static Display[] getDisplays(int capabilities)

can be used to obtain a list of all the Displays currently available, or a list of those which support a specified set of capabilities.

If capabilities is 0 then a list available Displays will be returned, with the primary Display first.

If capabilities is a bit-wise ORed combination of the runtime constants representing capabilities, then the list of Displays supporting those capabilities will be returned, with the primary Display first.

Note

The method documentation states

Since the Primary Display must support all capabilities, it is always returned as the first element regardless of the capabilities requested.

For this to be true the Primary display must not only support all the LCDUI features, but all the possible orientations as well. It is not clear what supporting all possible orientations entails nor whether it is necessarily feasible on every device.

10. Transient Secondary Displays

The physical display corresponding to a secondary Display can become unavailable. In this case the hardware state of the secondary Display will change to Absent. Once this happens the secondary Display is no longer usable, and calls to methods such as setCurrent(Displayable) will throw an IllegalStateException.

If the physical display corresponding to the secondary Display becomes available again it
will be reported as a new Display via a call to the DisplayaListener.displayAddedd(Display) method.

12. Backwards Compatibility

Some existing methods now throw new exceptions. For example, Display.setCurrent(Displayable) can now throw a DisplayCapabiltyException or an IllegalStateException. However, as required to ensure binary compatibility, all new exceptions thrown are RuntimeExceptions. In addition these exceptions cannot occur when using the Primary display which is the only Display that a legacy MIDlet has access to,


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

June 16, 2009

What’s New In MIDP 3.0 ? Part 11: javax.microedition.midlet.MIDlet

Filed under: Java, JME, MIDlets, MIDP, MIDP3, MIDP3API, Mobile Java — Tags: , , , , , — Simon Lewis @ 2:14 pm

There have been changes to existing javax.microedition.midlet.MIDlet methods to support the new MIDlet lifecycle model, and new methods have been added to support new MIDP 3.0 functionality.

1. Modified Method Contracts

1.1 destroyApp(boolean)


    protected abstract void destroyApp(boolean unconditional)
                            throws
                                MIDletStateChangeException

Originally if the value of the unconditional argument was false then a MIDlet could indicate that it did not want to be destroyed by throwing a MIDletStateChangeException.

This is no longer supported. The method will always be invoked with the unconditional argument set to true. Once the method has completed, normally, or by throwing an Exception, the MIDlet is considered to have been destroyed.

Note

In the current version of the specification the method documentation is badly mangled, although interestingly enough in different ways, in both the Javadoc and the PDF.

2 Deprecated Methods

2.1 public int checkPermission(String)

This method was originally defined in MIDP 2 to enable the checking of named permissions. As they are no longer supported it is now deprecated.

This method will continue to work if invoked by a legacy MIDlet, but will throw an IllegalStateException otherwise.

New MIDlets should use the java.security.AccessController.checkPermission(Permission) method to perform permission checking.

2.2 public final void notifyPaused()

MIDlets can no longer pause themselves.

New MIDlets should not use this method.

To support legacy MIDlets which have been implemented in terms of the notifyPaused()/resumeRequest() methods, this method will result in the MIDlet’s startApp() method being called immediately.

Notes

  1. It is not clear whether immediately means during the call to notifyPaused() itself, or after it has returned.
  2. It is not clear that this behaviour is actually going to ensure backwards compatibility. See here.

2.3 protected void pauseApp()

MIDlets are no longer paused using this method.

New MIDlets no longer have to implement this method. See below.

2.4 public final void resumeRequest()

As MIDlets are no longer paused and can no longer pause themselves there is no longer any need to be able to resume. This method has no effect when called. New MIDlets should not use it.

2.2. New Methods

2.2.1 public static String[] getAppProperty(String,String,String,String)


    public static String[] getAppProperty(
                               String name, 
                               String vendor, 
                               String attributeName, 
                               String attributeDelimiter)

This method can be used to get attributes defined by the MIDlet Suite containing the currently executing MIDlet, or defined by any of the LIBlets upon which that MIDlet Suite is dependent.

The method will tokenize the returned attribute value if a delimiter is specified.

The name argument specifies the name of the MIDlet Suite or LIBlet.

The vendor argument specifies the vendor of the MIDlet Suite or LIBlet.

The attributeName argument specifiers the name of the attribute to get.

The attributeDelimiter argument specifies the delimiter to use to tokenize the attribute value. If null then the value will not be tokenized.

The method returns an array of Strings if the attribute is found, null otherwise.

Note

As it is static LIBlet code can use this method to get attributes defined by the containing LIBlet, other LIBlets, or the MIDlet Suite. If it wishes to do so the LIBlet code will need some out-of-band mechanism to obtain the appropriate vendors and names as there is no programmatic way of obtaining them.

3.2 public final MIDletIdentity getMIDletIdentity()

This method returns the identity of this MIDlet as an instance of MIDletIdentity.

3.3 public final long getSplashScreenTime()

This method returns the number of milliseconds the splash screen, if any, associated with this MIDlet has been visible, or -1 if there is no splash screen associated with this MIDlet visible.

3.4 public final boolean isSelectedScreenSaver()

This method returns true if this MIDlet is the currently selected screensaver on the device, false otherwise.

4. New Concrete Methods

4.1 protected void pauseApp()

The pauseApp() method is no longer abstract. It was originally defined as abstract in MIDP 1.0, which ensured that a MIDlet developer had to implement it and at least in theory implement the appropriate behaviour if the MIDlet was paused.

As it has been deprecated and there is no need for it to be implemented on a per-MIDlet basis an implementation is now supplied.

June 12, 2009

What’s New In MIDP 3.0 ? Part 8: MIDletIdentity

Filed under: Java, JME, MIDP, MIDP3, MIDP3API, MIDP3Issues — Tags: , , , , , , — Simon Lewis @ 8:24 am

1. The Class

The class MIDletIdentity has been added to the package javax.microedition.midlet.

As the name suggests and the class documentation explicitly states

This class represents the identity of a MIDlet

An instance of MIDletIdentity is used to identify the source of an Event in the Event API.
and to identify clients and servers in the IMC API.

1.1 Methods

The class it very simple since an instance of MIDletIdentity is immutable. It has six methods

  • getName()
  • getVendor()
  • getVersion()
  • getSecurityDomain()
  • isAuthorized()
  • toString()

The methods

  • getName()
  • getVendor()
  • getVersion()

are defined to return

  • [the] Name of the MIDlet
  • [the] Version string of the MIDlet
  • [the] Vendor name of the MIDlet

respectively.

The method getSecurityDomain() is defined to return

  • [the] Name of the security domain that the MIDlet associated with this MIDletIdentity was bound to when it was installed.

If the security domain is one of the predefined ones, then the return value is guaranteed to be equal to one of the constants

  • IDENTIFIED_THIRD_PARTY
  • MANUFACTURER
  • OPERATOR
  • UNIDENTIFIED_THIRD_PARTY

The method isAuthorized() is defined to return

  • true if the MIDlet associated with the specified MIDletIdentity is authorized to the current MIDlet’s runtime execution environment, false otherwise.

The method toString() is defined to return

  • the String concatenation of getVendor() + “; ” + getName() + “; ” + getVersion().

2. Issues

Unfortunately an instance of MIDletInstance does not identify a MIDlet.

To begin with, while a MIDlet certainly has a name, it is has neither a vendor nor a version, although the
MIDlet Suite containing the MIDlet has both. In fact, the class documentation actually states

This class provides identity information for a specific MIDlet including suite name, vendor, version, …

which might suggest that the vendor and version being returned from getVendor(), and getVersion() are actually those of the MIDlet Suite containing the MIDlet, which would make sense. However it might also suggest that getName() returns the name of the MIDlet Suite containing the MIDlet.

If we assume, on the basis of the class documentation above, that the methods

  • getName()
  • getVendor()
  • getVersion()

actually return

  • the name
  • the vendor
  • the version

respectively, of the MIDlet Suite containing the MIDlet, we have a problem. There is now no MIDlet specific
information. What we have is a MIDlet Suite identity.

If we stick with the existing method documentation for getName() we have a different problem.
There is no MIDlet Suite name. What we have is a partial MIDlet identity.

3. The Solution(s)

3.1 Rename The Class

As it stands an instance of MIDletIdentity is a perfectly good MIDlet Suite identity, so
rename the class to MIDletSuiteIdentity and fix up all the documentation everywhere accordingly,

3.2 Fix The Class

Rename the methods

  • getName()
  • getVendor()
  • getVersion()

to

  • getMIDletSuiteName()
  • getMIDletSuiteVendor()
  • getMIDletSuiteVersion()

respectively

Add a

  • getMIDletClassName()

method, and update the documentation accordingly.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

June 5, 2009

What’s New In MIDP 3.0 ? Part 4: Inter-MIDlet Communication

Filed under: Java, JME, MIDP, MIDP3, MIDP3API, MIDP3IMCAPI — Tags: , , , , , — Simon Lewis @ 11:56 pm

1. Overview

Inter-MIDlet communication (IMC) is a connection based client/server mechanism accessed through the javax.microxedition.io Generic Connection framework (GCF).

2. The IMC Client/Server Model

A server has a name and a version.

Each version of the same server is backwards compatible with all preceeding versions.

A server may specify that only an authorized MIDlet can be a client.

A client connects to a server by specifying a name and a version.

A client may also specify that the required server must be implemented by a MIDlet in a given MIDlet suite.

A client may also specify that the required server must be implemented by an authorized MIDlet.

A MIDlet can implement one or more servers and/or be the client of one or more servers.

2.2 Connection URIs

Connection URIs are used in the GCF to specify a connection to open. IMC defines two different URI formats, one for opening a server connection, and one for opening a client connection to a server.

2.2.1 Server Connection URIs

An IMC server connection URI specifies the name, version, and authorization mode of a server, and is of the form

    "imc://:"<ServerName>":"<ServerVersion>";"[<AuthMode>]

The <ServerName> must be in the same format as a Java class name.

The <ServerVersion> must be in the same format as a MIDlet suite version.

The <AuthMode> must be in the form

    "authmode=("true"|"false")

If <AuthMode> is present and is authmode=true then only authorized MIDlets can be clients of the server.

2.2.2 Client Connection URIs

An IMC client connection URI specifies a server instance to connect to. Zero, one, or more server instances may match the specification.

A client connection URI is of the form

    "imc://"(<MIDletSuiteUID>|"*")":"<ServerName>":"<ServerVersion>";"[<AuthMode>]

A <MIDletSuiteUID> is of the form

    <MIDletSuite-Vendor>":"<MIDletSuite-Name>":"(<MIDletSuite-Version>|"*")

<MIDletSuite-Vendor> can be any legal MIDlet suite vendor id.

<MIDletSuite-Name> can be any legal MIDlet suite name.

<MIDletSuite-Version> can be any legal MIDlet suite version.

Note

In the specification <MIDletSuiteUID> is referred to as <MIDlet UID>. I would argue that this is a misnomer. The MIDlet suite vendor/name/version triple identifies a MIDlet suite not a MIDlet.

If <MIDletSuiteUID> is specified then a connection can only be made to a server instance implemented by a MIDlet in the specified MIDlet suite.

If the wildcard (*) is specified instead then a connection can be made to any eligible server instance. In this case, if there are multiple eligible server instances then it is implementation specific which one is connected to.

A <Server-Name> has the same format as a Java class name.

A <Server-Version> has the same format as a MIDlet suite version number.

<AuthMode> is of the form

    "authmode="("true"|"false")

If <AuthMode> is present and is authmode=true then a connection can only be made to a server instance implemented by an authorized MIDlet.

2.2.2.1 Client Connection URI Examples

2.2.2.1.1

any version 1.0 compatible instance of the server example.Server.

    imc://*:example.Server:1.0;

2.2.2.1.2

any version 1.0 compatible instance of the server example.Server implemented by an authorized MIDlet.

    imc://*:example.Server:1.0;authmode=true

2.2.2.1.3

the version 1.0 compatible instance of the server example.Server implemented by a MIDlet in version 1.5 of the ExampleMIDletsRUs vendor’s ExampleIMCMIDlets suite.

    imc://ExampleMIDletsRUs:ExampleIMCMIDlets:1.5:example.Server:1.0;

2.2.2.1.4

the version 1.0 compatible instance of the server example.Server implemented by an authorized MIDlet in version 1.5 of the ExampleMIDletsRUs vendor’s ExampleIMCMIDlets suite.

    imc://ExampleMIDletsRUs:ExampleIMCMIDlets:1.5:example.Server:1.0;authmode=true

2.2.2.1.5

the version 1.0 compatible instance of the server example.Server implemented by a MIDlet in any version of the ExampleMIDletsRUs vendor’s ExampleIMCMIDlets suite.

    imc://ExampleMIDletsRUs:ExampleIMCMIDlets:*:example.Server:1.0;

2.2.2.1.6

the version 1.0 compatible instance of the server example.Server implemented by an authorized MIDlet in any version of the ExampleMIDletsRUs vendor’s ExampleIMCMIDlets suite.

    imc://ExampleMIDletsRUs:ExampleIMCMIDlets:*:example.Server:1.0;authmode=true

3. The IMC API

3.1 IMCServerConnection

The IMCServerConnection interface is defined in the javax.microedition.io package. It extends the existing StreamConnectionNotifier interface defined in the same package.

An instance of IMCServerConnection is returned from a call to Connector.open() when passed a server connection URI. This instance can then be used to accept connections from clients.

The interface defines the following methods.

3.1.2 getName()

This method returns the name of the server as specified in the URI used to open the connection.

3.1.3 getVersion()

This method returns a String representing version of the server as specified in the URI used to open the connection.

3.2 IMCConnection

The IMCConnection interface is defined in the javax.microedition.io package. It extends the existing StreamConnectionNotifier interface defined in the same package.

An instance of IMCConnection is returned from a call to Connector.open() when passed a client connection URI,
but also from a call to StreamConnectionNotifier.acceptAndOpen() on an instance of IMCServerConnection.

The interface defines the following methods.

3.2.2 getRemoteIdentity()

This method returns an instance of the class javax.microedition.midlet.MIDletIdentity which represents the MIDlet at the other end of this connection.

When invoked on the client side the result will represent the server MIDlet.

When invoked on the server side the result will represent the client MIDlet.

Note

The MIDletIdentity class is a new class defined in MIDP 3.0. I would suggest that it is wrongly named since an instance of MIDletIdentity actually identifies the MIDlet suite containing the MIDlet rather than the MIDlet itself.

3.2.3 getRequestedServerVersion()

This method returns a String representing the server version specified in the client connection URI associated with this connection.

When invoked on the client side the associated client connection URI is the one used to open the connection.

When invoked on the server side the associated client connection URI is the one used to open the corresponding client connection.

Using this method a MIDlet implementing a server can determine which version of the server functionality the client is expecting.

3.2.4 getServerName()

This method returns the server name specified in the client connection URI associated with this connection.

When invoked on the client side the associated client connection URI is the one used to open the connection.

When invoked on the server side the associated client connection URI is the one used to open the corresponding client connection.

3. Opening A Client Connection To A Server

A client can open a connection to a server by invoking the Connector.open() method with a client connection URI.

If the call succeeds then an instance of IMCConnection will be returned.

The call can fail if no server with the specified name exists, if a server with the specified name exists but it does not support the specified version, or if a server with the specified name and supporting the specified version exists, but it is not implemented by a MIDlet in the specified MIDlet suite.

In each of these cases a ConnectionNotFundException will be thrown.

The call can fail if a server exists but it specifies that a client must be authorized and the caller is not. In this case a SecurityException will be thrown.

The call can fail if a server exists but the client specifies that it must be implemented by an authorized MIDlet and it is not. In this case a SecurityException will be thrown.

Code Fragment


import javax.micredition.io.Connector;
import javax.micredition.io.IMCConnection;

...

    IMCConnection imcc = (IMCConnection)Connector.open("imc://*:ExampleServer:1.0;");

...

4. Opening A Server Connection

A server connection can be opened by invoking the method Connector.open() with a server connection URI.

Note

It is not clear from the specification under what circumstances a call to Connector.open() with a server connection URI can fail. It is obviously (?) an error if a MIDlet attempts to open a server connection twice using the same server connection URI, and it is presumably an error if different MIDlets in the same MIDlet suite attempt to open a server connection using the same server connection URI. It is also presumably an error if a MIDlet attempts to open a server connection twice using a server connection URI which differs only in the specified authorization mode. However, is it an error if the same MIDlet or different MIDlets in the same MIDlet suite attempt to open server connections using server connection URIs which differ only in the specified version ?

Code Fragment


import javax.micredition.io.Connector;
import javax.micredition.io.IMCConnection;
import javax.micredition.io.IMCServerConnection;

...

    IMCServerConnection imcsc = null;
	
    imcsc = (IMCServerConnection)Connector.open("imc://:ExampleServer:1.0;");

...

5. Accepting Connections From Clients

Once a server connection has been opened, connections from clients can be accepted by calling the acceptAndOpen() method of the returned IMCServerConnection instance.

Once a client connection has been accepted the server can determine the server version expected by the client using the getRequestedServerVersion() method of the returned IMCConnection instance.

Code Fragment


import javax.micredition.io.Connector;
import javax.micredition.io.IMCConnection;
import javax.micredition.io.IMCServerConnection;

...

    IMCServerConnection imcsc = null;
	
    imcsc = (IMCServerConnection)Connector.open("imc://:ExampleServer:1.0;");

    while (true)
    {
        IMCConnection imcc    = (IMCConnection)imcsc.acceptAndOpen();
        String        version = imcc.getRequestedServerVersion();
		
        ...

    }

...

6. Push Connections

An IMC server connection can be registered as a push connection either statically at installation time, or dynamically using the PushRegistry.registerConnection() method, using a standard IMC server connection URI.

The <AllowedSender> element of the value of the MIDlet-Push-<n> attribute used for static registration, or the corresponding filter argument of the code>PushRegistry.registerConnection() method can be either a <MIDletSuiteUID> or the wildcard (*).

Note

As in the definition of a client connection URI the specification actually refers to <MIDlet UID>.

6.2 Static Registration Examples

6.2.1

MIDlet-Push-1: imc://:ExampleServer:1.0;,IMCExampleServerMIDlet,*

Register version 1.0 of the ExampleServer server. Connections will be accepted from any MIDlet.

6.2.2

MIDlet-Push-1: imc://:ExampleServer:1.0;authmode=true,IMCExampleServerMIDlet,*

Register version 1.0 of the ExampleServer server. Connections will be only be accepted from authorized MIDlets.

6.2.3

MIDlet-Push-1: imc://:ExampleServer:1.0;,IMCExampleServerMIDlet,MIDletsRUs:Examples:1.0

Register version 1.0 of the ExampleServer server. Connections will be only be accepted from MIDlets in version 1.0 of the MIDletsRUs Examples MIDlet suite.

6.3 Dynamic Registration Examples

6.3.1


import javax.microedition.io.PushRegistry;

...

    PushRegistry.registerConnection(
                     "imc://:ExampleServer:1.0;"
                     "IMCExampleServerMIDlet",
                     "*");
					 
...

Register version 1.0 of the ExampleServer server. Connections will be accepted from any MIDlet.

6.3.2


import javax.microedition.io.PushRegistry;

...

    PushRegistry.registerConnection(
                     "imc://:ExampleServer:1.0;authmode=true"
                     "IMCExampleServerMIDlet",
                     "*");
					 
...

Register version 1.0 of the ExampleServer server. Connections will be only be accepted from authorized MIDlets.

6.3.3


import javax.microedition.io.PushRegistry;

...

    PushRegistry.registerConnection(
                     "imc://:ExampleServer:1.0;authmode=true"
                     "IMCExampleServerMIDlet",
                     "MIDletsRUs:Examples:1.0");
					 
...

Register version 1.0 of the ExampleServer server. Connections will be only be accepted from MIDlets in version 1.0 of the MIDletsRUs Examples MIDlet suite.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

June 4, 2009

What’s New In MIDP 3.0 ? Part 3: Events

Filed under: Java, JME, MIDP, MIDP3, MIDP3API, MIDP3EventAPI — Tags: , , , , , — Simon Lewis @ 11:19 pm

1. The Event API

The event API is specified by a single interface

  • EventDataListener

and three classes

  • EventData
  • EventManager
  • EventPermission

all of which are defined in the javax.microedition.event package.

1.1 EventDataListener

The EventDataListener interface defines a single method

    void handleEvent(EventData event)

1.2 EventData

An event is represented by an instance of EventData.

1.2.1 Fields

Each event has a name, and a typed value. When received by a MIDlet an event will also have a timestamp and a source. Each event may also have an optional message and an optional information object.

1.2.1.1 Name

The name of an event is either that of a pre-defined system event, or is application specific.

In the case of an application specific name the specification suggests, but does not require, that the reverse domain name convention should be adopted, and that the name have at least two components.

For example

    com.midletsrus.event.example

The name of an event can be accessed using the method getName().

1.2.1.2 Value

The value of an event may be of one of the following types

  • boolean
  • double
  • long
  • String

The value of an event can be accessed either by using one of the following type specific methods

  • getBoolean()
  • getDouble()
  • getFloat()
  • getInt()
  • getLong()
  • getString()

each of which returns a value of the appropriate type, or the method

     getValue()

which returns an instance of the Java class corresponding to the underlying value type.

Note

If the actual value of the event is a string, each of the numeric type-specific methods will attempt to parse the string as a number of the appropriate type. This may result in a NumberFormatException.

1.2.1.3 Timestamp

When received by a MIDlet an event will have a valid timestamp equivalent to the result of calling the method System.currentTimeMillis() at the time the event was posted.

The timestamp can be accessed using the method getTimestamp().

1.1.1.4 Source

When received by a MIDlet an event will have a source which can be used to identify the originator of the event.

The source can be accessed by using the method getSourceInfo().

This method returns an instance of the class MIDletIdentity if the event was posted by a MIDlet, null otherwise.

Note

The class MIDletIdentity is a new class defined in the javax.microedition.midlet package which provides access to information about the MIDlet suite containing a given MIDlet.

1.1.1.5 Message

An event may have an optional message of type String which can be accessed using the getMessage() method.

1.1.1.6 Information Object

An event may have an optional information object which can be accessed using the getInfo() method. The instance of Object returned by this method is constrained to be of one of the following types.

  • Boolean
  • Double
  • Long
  • String
  • byte[]

or null if there is no information object.

Note

The information object can in theory be used by an application to associate additional arbitrary information with an event. However, the specification only requires that an implementation support the passing of at least 1024 bytes of data inclusive of the name, value, message, and information object, so it is not a guaranteed way of passing unlimited amounts of data.

1.1.2 Constructors

There are four constructors which enable the creation of instances of EventData with values of each of the permitted types, and a name, message, and information object.

Note

The specification states that the constructors can be used to create representations of both system and application specific events. It does not, however, require that an implementation ensure that the value supplied for a system event is legal. Nor does it specify any constraints on the use of the message and the information object in the system event case.

1.1.3 System Events

The EventData class defines a number of constants which specify the names and possible values of system events (see below). The specification does not explicitly state that all the defined system events must be supported, but it does expicitly state that additional system events may be supported by a specific implementation and/or device.

For each system event below, the constant defining the name is in parentheses, and the value type is after the colon.

1.1.3.1 Audio Mute Event (AUDIO_MUTE): boolean

true if all audio output devices are muted.

1.1.3.2 Backlight Event (BACKLIGHT): int

Legal values are defined by the constants

  • BACKLIGHT_OFF
  • BACKLIGHT_ON
  • BACKLIGHT_DIM

1.1.3.3 Battery Charging Event (BATTERY_CHARGING): boolean

true if battery is charging.

1.1.3.4 Battery Level Event (BATTERY_LEVEL): int

Legal values are 1 to 100 inclusive

1.1.3.5 Battery Low Event (BATTERY_LOW): true

true if battery is low.

1.1.3.6 Data Network Event (DATA_NETWORK): String

The value specifies the currently available data networks as a semi-colon separated list of values defined by the following constants

  • NETWORK_3GPP_CSD
  • NETWORK_3GPP_PD
  • NETWORK_3GPP_PD_EDGE
  • NETWORK_3GPP_PD_3G
  • NETWORK_3GPP_PD_HSDPA
  • NETWORK_802DOT11
  • NETWORK_802DOT16
  • NETWORK_CDMA

1.1.3.7 External Power Event (EXTERNAL_POWER): boolean

true if device is connected to an external power source.

1.1.3.8 Flight Mode Event (FLIGHT_MODE): boolean

true if device is in flight mode.

1.1.3.9 Profile Activated Event (PROFILE_ACTIVATED): String

Legal values are defined by the constants

  • PROFILE_GENERAL
  • PROFILE_SILENT
  • PROFILE_MEETING
  • PROFILE_OUTDOOR
  • PROFILE_PAGER
  • PROFILE_OFFLINE
  • PROFILE_USER1
  • PROFILE_USER2
  • PROFILE_USER3
  • PROFILE_USER4
  • PROFILE_SYSTEM1
  • PROFILE_SYSTEM2
  • PROFILE_SYSTEM3
  • PROFILE_SYSTEM4

1.1.3.10 Screensaver Mode Event (SCREENSAVER_MODE): String

Legal values are defined by the constants

  • SCREENSAVER_MODE_ACTIVATED
  • SCREENSAVER_MODE_DEACTIVATED

1.1.3.11 System State Event (SYSTEM_STATE): String

Legal values are defined by the constants

  • SYSTEM_STATE_STARTUP
  • SYSTEM_STATE_NORMAL
  • SYSTEM_STATE_SHUTDOWN
  • SYSTEM_STATE_STANDBY

1.1.3.12 Voice Call Event (VOICE_CALL): boolean

true if at least one voice call is active.

1.1.4 Application Relaunch Events

When an attempt is made to launch an already running MIDlet an application relaunch system event is generated.

The name of this event is a concatenation of the value of the constant APPLICATION_RELAUNCH_PREFIX and the vendor, name, and version of the MIDlet suite containing the relaunched MIDlet formatted as specified by the documentation of the MIDletIdentity.toString() method.

1.1.5 System Property Events

The specification states that an implementation may choose to support system events for changes to system properties, with the name of the event being the same as that of the corresponding system property.

1.2 EventManager

A MIDlet can call methods on an instance of the EventManager class to perform the following functions

  • adding and removing event listeners
  • registering and unregistering a MIDlet for launch in response to an event
  • posting an event
  • listing the supported system events
  • getting a system event

A MIDlet can obtain an EventManager instance by calling the static method getInstance().

1.2.1 Adding An Event Listener

A MIDlet can receive events by registering an object which implements the EventDataListener interface as an event listener with the event manager, using an appropriate variant of the addEventListener() method to specify the criteria an event should match.

A MIDlet must specify the name of the event to listen for, or an event name prefix which the name of the event should match, and the authorization mode, which specifies whether the source of the event must be authorized with respect to the invoking MIDlet.

Note

It is not clear whether the authorization mode applies to system events since they are not necessarily posted by a MIDlet. I currently assume that it does not.

Event names are case-sensitive.

An event name prefix is a string of at least one character with the suffix ‘*’. The name of an event matches the pattern if the specified pattern excluding the trailing ‘*’ is a prefix of the event name.

A MIDlet may also specify a constraint on the value of an event, the exact nature of the constraint depending upon the type of the event value.

A MIDlet may only register an event listener if the MIDlet suite containing it has been granted the appropriate permission. (see EventPermission)

If all the specified criteria are met when a given event occurs, then the handleEvent(EventData) method of the registered event listener is invoked with an instance of EventData representing the matching event. The instance of EventData is only guaranteed to be valid for the duration of the call.

Note

If the call to addEventListener() specifies a system event, and the current system event matches the specified criteria then the event listener will be invoked immediately with the matching system event.

It is not clear whether there is any guarantee as to when this occurs relative to the call to addEventListener().

An event listener may be added for multiple values or value ranges of the same event or events.

Note

It is not clear what the intended behaviour is if two calls of addEventListener() differing only in the value of the authorization mode are performed.

There are a total of five variants of the addEventListener() method corresponding to the four possible event value types plus the case where there is no constraint on the event value.

1.2.1.1 addEventListener(String, EventDataListener, boolean)

The first argument is the event name, or event name prefix.

The second argument is an instance of an object implementing the EventDataListener interface.

The third argument is the required authorization mode. If the value is true then the source of an event must be authorized with respect to the invoking MIDlet. If the value is false then the event source is ignored.

Code fragment

Listen for application specific example.event.public events from any MIDlet, assuming the invoker implements the EventDataListener interface.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.addEventListener("example.event.public", this, false);

...

Code fragment

Listen for application specific example.event.public events from authorized MIDlets only, assuming the invoker implements the EventDataListener interface.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.addEventListener("example.event.public", this, true);

...

1.2.1.2 addEventListener(String, EventDataListener, boolean, boolean)

The first three arguments are as above.

The fourth argument specifies the required value of the event.

It is an error if the specified event is a system event and its value is not defined to be of type boolean.

Code Fragment

Listen for application specific example.event.boolean events with the value of true from any MIDlet, assuming the invoker implements the EventDataListener interface.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.addEventListener("example.event.boolean", this, false, true);

...

1.2.1.3 addEventListener(String, EventDataListener, boolean, double, double)

The first three arguments are as above.

The fourth and fifth argument specify the inclusive lower and upper bounds of the range within which the value of the event should lie.

Neither the lower or upper bound may be NaN, and the specified lower bound must be less than or equal to the specified upper bound.

It is an error if the specified event is a system event and its value is not defined to be of type double, or if either of the specified values is not legal for that system event.

Code Fragment

Listen for application specific example.event.temperature events with a value between 0.0 and 20.0 from any MIDlet, assuming the invoker implements the EventDataListener interface.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.addEventListener("example.event.temperature", this, false, 0.0D, 20.0D);

...

1.2.1.4 addEventListener(String, EventDataListener, boolean, long, long)

The first three arguments are as above.

The fourth and fifth arguments specify the inclusive lower and upper bounds respectively of the range within which the value of the event should lie.

The specified lower bound must be less than or equal to the specified upper bound.

It is an error if the specified event is a system event and its value is not defined to be of type int or long, or if either of the specified values is not legal for that system event.

Note

The specification actually states an IllegalArgumentException should be thrown if

the named event is a system event and is known not to be an int event.

I have assumed this should actually be int or long

Code Fragment

Listen for application specific example.event.altitude events with a value between 1000 and 1500, or 2000 and 2500 from any MIDlet, assuming the invoker implements the EventDataListener interface.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.addEventListener("example.event.altitude", this, false, 1000L, 1500L);
    em.addEventListener("example.event.altitude", this, false, 2000L, 2500L);

...

1.2.1.5 addEventListener(String, EventDataListener, boolean, String[])

The first three arguments are as above.

The fourth argument specifies the set of event values of interest.

It is an error if the specified event is a system event and its value is not defined to be of type String.

Code Fragment

Listen for screensaver activated events, assuming the invoker implements the EventDataListener interface.


import javax.microedition.event.EventData;
import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.addEventListener(
           EventData.SCREENSAVER_MODE,
           this,
           false,
           new String[]
           {
               EventData.SCREENSAVER_MODE_ACTIVATED
           });
		   
...

Code Fragment

Listen for screensaver activated and deactivated events, assuming the invoker implements the EventDataListener interface.


import javax.microedition.event.EventData;
import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.addEventListener(
           EventData.SCREENSAVER_MODE,
           this,
           false,
           new String[]
           {
               EventData.SCREENSAVER_MODE_ACTIVATED,
               EventData.SCREENSAVER_MODE_DEACTIVATED
           });
		   
...

1.2.2 Removing An Event Listener

A MIDlet can remove an event listener by calling the

    removeEventListener(String event, EventDataListener listener) 

method.

The MIDlet must specify the event and the event listener to unregister.

The event can be specified as a name, as a prefix, or as a wildcard, the string “*”, which matches all events.

Note

It is not clear from the specification what the semantics of this method actually are. For example, what happens if an event listener was registered using a prefix, but is unregistered with a name which matches the prefix ? Presumably the event listener is removed for all events which match the prefix it was added with, despite the fact that it was specified for removal for a specific event ?

1.2.3 Adding An Application Launch On Event Registration

A MIDlet can register itself or another MIDlet in the same MIDlet suite to be launched when a given event occurs using an appropriate version of the registerApplication() method.

The criteria specifying the event or events to launch are are identical to those used when adding an event listener using addEventListener().

If all the specified criteria are met and the MIDlet is not already running then it will be launched.

Note

If the call to registerApplication() specifies a system event, and the current system event matches the specified criteria then the specified MIDlet will be launched immediately.

A MIDlet can only register an application for launch on event if the MIDlet suite containing it has been granted the appropriate permission. (see EventPermission)

A MIDlet can be registered for launch for multiple values or value ranges of the same event.

Note

It is not clear what the intended behaviour is if two identical registrations differing only in the value of the authorization mode are performed.

As with the addEventListener()method there are five variants of the registerApplication() method.

1.2.3.1 registerApplication(String, String, boolean)

The first argument specifies the event to launch on and must be a specific event name, or an event name prefix

The second argument specfies the MIDlet to be launched and must be the fully qualified name of a sub-class of javax.microedition.midlet.MIDlet which has been explicitly declared as a MIDlet by the MIDlet suite using a MIDlet-<n> attribute.

The third argument specifies the authorization mode. If specified as true then for the application to be launched an event must originate from an authorized MIDlet.

Code Fragment

Register the MIDlet implemented by the class example.event.EventMIDlet to launch when an application specific example.event.public event originating from any MIDlet occurs.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.registerApplication("example.event.public", "example.event.EventMIDlet", false);
		   
...

Code Fragment

Register the MIDlet implemented by the class example.event.EventMIDlet to launch when an application specific example.event.public event originating from an authorized MIDlet occurs.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.registerApplication("example.event.public", "example.event.EventMIDlet", true);
		   
...

1.2.3.2 registerApplication(String, String, boolean, boolean)

The first three arguments are as above.

The fourth argument is the boolean value the specified event should have for the MIDlet to be launched.

It is an error if the specified event is a system event and its value is not defined to be of type boolean.

Code Fragment

Register the MIDlet implemented by the class example.event.EventMIDlet to launch when an application specific example.event.boolean event with a value of true originating from any MIDlet occurs.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.registerApplication(
          "example.event.boolean", 
          "example.event.EventMIDlet", 
          false, 
          true);
		   
...

1.2.3.3 registerApplication(String, String, boolean, double, double)

The first three arguments are as above.

The fourth and fifth arguments specify the inclusive lower and upper bounds respectively within which the event value should lie for the MIDlet to be launched.

Neither specified value may be NaN, and the specified lower bound must be less than or equal to the specified upper bound.

It is an error if the specified event is a system event and its value is not defined to be of type double, or if either of the specified values are not legal for the event.

Code Fragment

Register the MIDlet implemented by the class example.event.EventMIDlet to launch when an application specific example.event.temperature event with a value between 0.0 and 20.0, originating from any MIDlet occurs.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.registerApplication(
          "example.event.temperature", 
          "example.event.EventMIDlet", 
          false, 
          0.0D, 
          20.0D);
		   
...

1.2.3.4 registerApplication(String, String, boolean, long, long)

The first three arguments are as above.

The fourth and fifth arguments specify the lower and upper bounds respectively within which the event value should lie for the MIDlet to be launched.

The specified lower bound must be less than or equal to the specified upper bound.

Note

For this variant of the registerApplication() method the specification does not explicitly state that it is an error if the caller specifies a system event whose value is not defined to be of type long, as it does for the double variant above, or the equivalent variant of addEventListener().

Code Fragment

Register the MIDlet implemented by the class example.event.EventMIDlet to launch when an application specific example.event.altitude event with a value between 1000 and 1500 or between 2000 and 2500 originating from any MIDlet occurs.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.registerApplication(
          "example.event.altitude", 
          "example.event.EventMIDlet", 
          false, 
          1000L, 
          1500L);
    em.registerApplication(
          "example.event.altitude", 
          "example.event.EventMIDlet", 
          false, 
          2000L, 
          2500L);
		   
...

1.2.3.5 registerApplication(String, String, boolean, String[])

The first three arguments are as above.

The fourth argument specifies the possible values an event should have for the MIDlet to be launched.

It is an error if the specified event is a system event and its value is not defined to be of type String, or one or more of the specified values are not defined as legal for that event.

Code fragment

Register the MIDlet implemented by the class example.event.EventMIDlet to launch when an application specific example.event.colour event with a value of, red, green, or blue, originating from any MIDlet occurs.


import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    em.registerApplication(
           "example.event.colour", 
           "example.event.EventMIDlet", 
           false, 
           new String[]
           {
               "red",
               "blue",
               "green"
           });
 	   
...

1.2.4 Removing An Application Launch On Event Registration

A MIDlet can remove a registration for an application launch on event by using the

    unregisterApplication(String event, String application)

method.

The first argument specifies the event, and must be either an event name, or an event name prefix.

The second argument specifies the MIDlet class, and must be a fully qualified class name.

It is an error if the specified class does not exist.

This method will remove registrations added using variants of the registerApplication() method and those added at installation time.

1.2.5 Posting An Event

A MIDlet can post an event by calling the method

    post(EventData event, boolean authmode). 

The first argument is an instance of EventData representing the event to be posted.

The second argument specifies whether the event should only be delivered to MIDlets which are authorized with respect to the posting
MIDlet.

This method is asynchronous, that is, it returns before the event has been delivered.

A MIDlet may only post an event if the MIDlet suite containing it has been granted the appropriate permission. (see EventPermission)

Code fragment

Post an event visible to any MIDlet


import javax.microedition.event.EventData;
import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    // Create the event
	
    Event e  = new EventData("example.event.public", "the event value", null, null);
	
    // Post the event 
	
    em.post(e, false);
	
...

Code fragment

Post an event visible only to authorized MIDlets


import javax.microedition.event.EventData;
import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    // Create the event
	
    Event e  = new EventData("example.event.private", "the event value", null, null);
	
    // Post the event 
	
    em.post(e, true);
	
...

1.2.6 Listing The Supported System Events

A MIDlet can obtain a ‘list’ of the supported system events by calling the getSystemEvents(). The method returns an array of strings

1.2.7 Getting A System Event

A MIDlet can obtain an instance of EventData representing a given system event by calling the

    getCurrent(String event) 

method passing the name of the required system event.

The method returns null if the event specified is not a known system event.

A MIDlet may only get a specific system event if the MIDlet suite containing it has been granted the appropriate permission. (see EventPermission)

Note

It is not entirely clear from the specification what this method is actually doing. I think that the implication is that any supported system event always corresponds to a system state, and the value of the event is always the current state. A call to getCurrent(String) therefore always returns a system event whose value is the current value of the corresponding system state.
</p

Code fragment


import javax.microedition.event.EventData;
import javax.microedition.event.EventManager;

...

    EventManager em = EventManager.getInstance();
	
    // Get the current system state 
	
    String systemState = em.getCurrent(EventData.SYSTEM_STATE).getString();
	
...

1.3 EventPermission

An EventPermission has a target name which specifies the event or events to which it applies, and one or more actions which it grants for the specified event or events.

1.3.1 Target Name

The target name may be a specific event name, an event name prefix, or the wildcard pattern.

An event name prefix is of the form

    <event-name-prefix>*

where <event-name-prefix>* must end with a ‘.’ (dot).

An event name prefix matches any event name with the specified prefix.

Note

This definition of event name prefix is not quite the same as that defined for the

    addEventListener()

and

    registerApplication()

methods

The wildcard pattern is the string “*” and matches all events

1.3.2 Actions

The three actions defined for an EventPermission are

  • post
  • read
  • register

1.3.2.1 Post

The post action controls the use of the

     post(Event, boolean) 

method.

For a MIDlet to successfully post an event, the MIDlet suite containing it must have been granted an EventPermission whose target name matches the name of the event being posted, and whose actions include post.

1.3.2.2 Read

The read action controls the use of both the

    getCurrent(String)

method, and all variants of the

    addEventListener()

method.

For a MIDlet to successfully get a current system event, or register a listener for an event, the MIDlet suite containing it must have been granted an EventPermission whose target name matches that event, and whose actions include read.

1.3.2.3 Register

The register action controls the use of all variants of the

     registerApplication() 

method.

For a MIDlet to successfully use any variant of the registerApplication() method, the MIDlet suite containing it must have been granted an EventPermission whose target name matches the event being registered for and whose actions include register.

2. Installation Time Registration For Application Launch On Event

At installation time a MIDlet suite can register a MIDlet for launch when a given event occurs by specifying one or more

    MIDlet-Event-Launch-<n> 

attributes in the manifest of the MIDlet suite JAR.

The ordinals should start at 1 and be consecutive. All MIDlet-Event-Launch-<n> attributes after the first gap, if any, are ignored.

The value of the attribute is of the form

    <Classname>;<AuthorizationMode>;<Launch-Condition>

ClassName

The value of <Classname> must be the full name of a sub-class of javax.microedition.midlet.MIDlet which implements the application to launch.

Note

In the case of the registerApplication() methods the specification also states that the class must have been explicitly declared as a MIDlet via a MIDlet-<n> attribute. For consistency I would assume that the same constraint applies here.

AuthorizationMode

The value of <AuthorizationMode> must be either true or false. If true then the MIDlet will only be launched if the matching event originates from an authorized MIDlet.

Launch-Condition

The value of <Launch-Condition> can be of the form

    <Event-Name>

or, for an event with a boolean value

    <Event-Name>="true"|"false"

or, for an event with a double value

    <Event-Name>=<Double-Event-Value>,<Double-Event-Value>

or, for an event with a long value

    <Event-Name>=<Long-Event-Value>,<Long-Event-Value>

or, for an event with a String value

    <Event-Name>= ‘"’<String-Event-Value>‘"’ [ , ‘"’<String-Event-Value>‘"’ ]*

The value of <Event-Name> must be the name of an event.

The value of <Double-Event-Value> must be a double literal as accepted by the method

    java.lang.Double.valueOf(String s).

Note

This definition is ambiguous.

The documentation of the method in CLDC 1.1.1 reads as follows

Leading and trailing whitespace characters in s are ignored. The rest
of s should constitute a FloatValue as described
by the lexical rule:


 FloatValue:

        Signopt FloatingPointLiteral
 

The documentation of the method in CDC 1.1 reads as follows

Leading and trailing whitespace characters in s
are ignored. The rest of s should constitute a
FloatValue as described by the lexical rule:

FloatValue:

Signopt NaN

Signopt Infinity

Signopt FloatingPointLiteral

The value of <Long-Event-Value> must be a long literal as accepted by the method

    java.lang.Long.valueOf(String s).

Note

The method

    java.lang.Long.valueOf(String s).

is not actually defined in CLDC, only CDC.

Note

The format of <String-Event-Value> is not particularly well defined by the specification
which merely states that

The event value is quoted and can not contain a quote.

For both the double and long value cases the supplied values specify the inclusive lower and upper bounds respectively within which the event value should lie.

Examples

The examples all assume that the following also appears in the manifest of the MIDlet suite JAR.

MIDlet-1: EventExampleMIDlet, EventExampleMIDlet.png, example.event.MIDlet

Event Name Only

Register the MIDlet EventExampleMIDlet to be launched when an example.event.public event originating from any MIDlet occurs.

MIDlet-Event-Launch-1: example.event.MIDlet;false; example.event.public

Register the MIDlet EventExampleMIDlet to be launched when an example.event.public event originating from an authorized MIDlet occurs.

MIDlet-Event-Launch-1: example.event.MIDlet;true; example.event.public

Event With Boolean Value

Register the MIDlet EventExampleMIDlet to be launched when an example.event.boolean event occurs with a value of true. The event source is ignored.

MIDlet-Event-Launch-1: example.event.MIDlet;false;example.event.boolean=true

Event With Double/Float Value

Register the MIDlet EventExampleMIDlet to be launched when an example.event.temperature event occurs with a value between 0.0 and 20.0. The event source is ignored.

MIDlet-Event-Launch-1: example.event.MIDlet;false;example.event.temperature=0.0,20.0

Event With Int/Long Value

Register the EventExampleMIDlet to be launched when an example.event.altitude event occurs with a value between 1000 and 1500, or 2000 and 2500. The event source is ignored.

MIDlet-Event-Launch-1: example.event.MIDlet;false;example.event.altitude=1000,1500
MIDlet-Event-Launch-2: example.event.MIDlet;false;example.event.altitude=2000,2500

Event With String Value

Register the EventExampleMIDlet to be launched when an example.event.colour event occurs with a value of red, green, or blue. The event source is ignored.

MIDlet-Event-Launch-1: example.event.MIDlet;false;example.event.colour="red","green","blue"

Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

Blog at WordPress.com.