17.6 Sample Usage Scenarios
This section provides two examples of MIDlets that are launched in response to a network notification. The first example is a Chat application that uses a well-known port for communication. The second example is a Ping application that dynamically allocates a port the first time it is started.
1 Sample Chat Application
The Chat application uses push to receive a message on a well-known port. In order to concentrate on the push functionality, it does not show any corresponding MIDlet that would enable the user to reply to the message.
Note
This sample is appropriate for bursts of datagrams because it loops on the connection, processing received messages.
The JAD file for the Chat application's MIDlet suite includes a static push connection registration shown in boldface. It also includes an indication that this MIDlet requires permission to use a datagram connection for inbound push messages. The following example code shows the JAD file:
MIDlet-Name: SunNetwork - Chat Demo
MIDlet-Version: 1.0
MIDlet-Vendor: Sun Microsystems, Inc.
MIDlet-Description: Network demonstration programs for MIDP
MicroEdition-Profile: MIDP-2.0
MicroEdition-Configuration: CLDC-1.0
MIDlet-1: InstantMessage, /icons/Chat.png, example.chat.SampleChat
MIDlet-Push-1: datagram://:79, example.chat.SampleChat, *
MIDlet-Permissions: javax.microedition.io.PushRegistry, javax.microedition.io.Connector.
datagramreceiver
The following example code shows the Chat MIDlet. The startApp method launches a thread to handle the incoming data. (An inner class implements the Runnable interface.) Using a separate thread to handle network I/O is the recommended practice. It avoids conflicts between blocking I/O operations and user-interaction events. The thread receives messages until the MIDlet is destroyed.
public class SampleChat extends MIDlet {
// Current inbound message connection
DatagramConnection conn;
// Flag to terminate the message reading thread
boolean done_reading;
public void startApp() {
// List of active connections
String connections[];
// Check to see if this session was started due to
// inbound connection notification
connections = PushRegistry.listConnections(true);
// Start an inbound message thread for available
// inbound messages for the statically configured
// connection in the application descriptor
for (int i=0; i < connections.length; i++) {
Thread t = new Thread(
new MessageHandler(connections[i]));
t.start();
}
...
}
// Stop reading inbound messages and release the push
// connection to the AMS listener
public void destroyApp(boolean conditional) {
done_reading = true;
if (conn != null)
conn.close();
// Optionally, notify network service that we're
// done with the current session
...
}
// Optionally, notify network service
public void pauseApp() {
...
}
// Inner class to handle inbound messages on separate thread
class MessageHandler implements Runnable {
String connUrl ;
MessageHandler(String url) {
connUrl = url;
}
// Fetch messages in a blocking receive loop
public void run() {
try {
// Get a connection handle for inbound messages
// and a buffer to hold the inbound message.
DatagramConnection conn = (DatagramConnection)
Connector.open(connUrl);
Datagram data = conn.newDatagram(
conn.getMaximumLength());
// Read the inbound messages
while (!done_reading) {
conn.receive(data);
...
}
} catch (IOException ioe) {
...
}
}
2 Sample Ping Application
The Ping application uses push to receive a a datagram and echo it back to the sender. Pings are often used to check whether a network entity is operational.
In this sample, the JAD file associated with the Ping application's MIDlet suite includes an entry (shown in boldface) indicating that the application will need permission to use the datagram connection for inbound push messages. It does not statically register for push notifications, however. The following example code shows the JAD file:
MIDlet-Name: SunNetwork - Demos
MIDlet-Version: 1.0
MIDlet-Vendor: Sun Microsystems, Inc.
MIDlet-Description: Network demonstration programs for MIDP
MicroEdition-Profile: MIDP-2.0
MicroEdition-Configuration: CLDC-1.0
MIDlet-1: JustCallMe, /icons/Ping.png, example.ping.SamplePingMe
MIDlet-Permissions: javax.microedition.io.PushRegistry,
javax.microedition.io.Connector.datagramreceiver
The following example code shows the Ping MIDlet. The first time it is run, the MIDlet opens a connection and allows the device to assign it an available port. It uses the open connection during the first session to dynamically register the connection with the push registry and to send the connection to the network entity that might ping the device. The MIDlet can reopen the connection in subsequent sessions in response to a inbound connection notification.
public class SamplePingMe extends MIDlet {
// Name of the current application for push registration.
String myName = "example.chat.SamplePingMe";
// List of registered push connections.
String connections[];
// Inbound datagram connection
UDPDatagramConnection dconn;
public SamplePingMe() {
// Check to see if the ping connection has been registered.
// This is a dynamic connection allocated on first-time
// execution of this MIDlet.
connections = PushRegistry.listConnections(false);
if (connections.length == 0) {
// Request a dynamic port for out-of-band notices.
// (Omitting the port number has the system allocate
// an available port number.)
try {
dconn = (UDPDatagramConnection)
Connector.open("datagram://");
String dport =
"datagram://:" + dconn.getLocalPort();
// Register the port so the MIDlet will wake up,
// if messages are posted after the MIDlet exits.
PushRegistry.registerConnection(dport,myName,"*");
// Post my datagram address to the network
...
} catch (IOException ioe) {
...
} catch (ClassNotFoundException cnfe) {
...
}
}
}
public void startApp() {
// Open the connection if it's not already open
if (dconn == null) {
// This is not the first time this is run, because the
// dconn has not been opened by the constructor
// Check whether the startup has been due to an incoming
// datagram
connections = PushRegistry.listConnections(true);
if (connections.length > 0) {
// Open the pending datagram that can be received
dconn = (UDPDatagramConnection)
Connector.open(connections[0]);
// Read the datagram
Datagram d = dconn.newDatagram(
dconn.getMaximumLength());
dconn.receive(d);
} else {
// There are no pending datagrams, but open
// the connection for later use
connections = PushRegistry.listConnections(false);
if (connections.length > 0) {
dconn = (UDPDatagramConnection)
Connector.open(connections[0]);
}
}
}
}
public void destroyApp(boolean unconditional) {
// Close the connection before exiting
if (dconn != null){
dconn.close();
dconn = null;
}
}
|