The MIDlet main class controls the state changes between the MIDlet
UI screens. It also owns the message connection and registers itself
as a message listener waiting for incoming messages. When a message
needs to be sent, the sendMessage
method launches
a new thread that takes care of sending the message. The application
ID used for the connection in both ends is also defined in the MIDlet
main class.
To implement the MIDlet main class:
Create the MMSMIDlet.java
class file.
Import the required classes.
import java.io.IOException; import javax.microedition.io.Connector; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable; import javax.microedition.midlet.MIDlet; import javax.wireless.messaging.Message; import javax.wireless.messaging.MessageConnection; import javax.wireless.messaging.MessageListener; import javax.wireless.messaging.MessagePart; import javax.wireless.messaging.MultipartMessage; import javax.wireless.messaging.SizeExceededException;
Set MMSMIDlet
to extend MIDlet
and implement MessageListener
. The MIDlet uses the MessageListener
interface to receive notifications of incoming
messages.
// Main MIDlet class. // This controls the user interface and the MMS connection public class MMSMIDlet extends MIDlet implements MessageListener {
Create the required
variables, and create the MMSMIDlet
class constructor.
private final String APPLICATION_ID = "mmsdemo"; private CameraScreen cameraScreen = null; private ReceiveScreen receiveScreen; private SendScreen sendScreen; private InfoScreen infoScreen; private Displayable resumeDisplay = null; private MessageConnection messageConnection; private Message nextMessage = null; public MMSMIDlet() { }
The MessageConnection
interface defines the basic
functionality for sending and receiving messages. It contains methods
for sending and receiving messages, factory methods to create a new Message
object, and a method that calculates
the number of segments of the underlying protocol that are needed
to send a specified Message
object. Message
is the base interface for derived interfaces that represent various
types of messages.
Define the mandatory lifecycle methods for starting, pausing, and destroying the MIDlet.
public void startApp() { if (resumeDisplay == null) { // Start the MMS connection startConnection(this); // Create the user interface cameraScreen = new CameraScreen(this); infoScreen = new InfoScreen(); sendScreen = new SendScreen(this); Display.getDisplay(this).setCurrent(cameraScreen); resumeDisplay = cameraScreen; cameraScreen.start(); } else { Display.getDisplay(this).setCurrent(resumeDisplay); } } public void pauseApp() { if (Display.getDisplay(this).getCurrent() == cameraScreen) { cameraScreen.stop(); } } public void destroyApp(boolean unconditional) { if (Display.getDisplay(this).getCurrent() == cameraScreen) { cameraScreen.stop(); } } void exitApplication() { closeConnection(); destroyApp(false); notifyDestroyed(); }
Create a method for receiving incoming messages.
private synchronized void receive(Message incomingMessage) { if (receiveScreen == null) { receiveScreen = new ReceiveScreen(this); } receiveScreen.setMessage(incomingMessage); Display.getDisplay(this).setCurrent(receiveScreen); }
Implement the notifyIncomingMessage
callback method for
incoming messages. This method starts a new thread for receiving the
message.
public void notifyIncomingMessage(MessageConnection conn) { // Callback for inbound message. // Start a new thread to receive the message. new Thread() { public void run() { try { Message incomingMessage = messageConnection.receive(); // this may be called multiple times if // multiple messages arrive simultaneously if (incomingMessage != null) { receive(incomingMessage); } } catch (IOException ioe) { showError("Exception while receiving message: " + ioe.getMessage()); } } }.start(); }
Create a method for sending a message.
void sendMessage(String recipientAddress, MessagePart imagePart, MessagePart textPart) { try { // The MMS message is constructed here. // It is a multipart message consisting of two parts: // image and text. MultipartMessage mmsMessage = (MultipartMessage) messageConnection .newMessage(MessageConnection.MULTIPART_MESSAGE); mmsMessage.setAddress(recipientAddress); mmsMessage.addMessagePart(imagePart); mmsMessage.addMessagePart(textPart); nextMessage = mmsMessage; // Send the message in another thread new Thread() { public void run() { try { messageConnection.send(nextMessage); } catch (IOException ioe) { showError("Exception while sending message: " + ioe.getMessage()); } } }.start(); } catch (SizeExceededException see) { showError("Message size is too big."); } catch (IllegalArgumentException iae) { showError("Phone number is missing."); } }
The MultipartMessage
interface represents a multipart
message into which instances of the MessagePart
class can be added. The newMessage
method constructs a new message object of a given
type. The setAddress
method sets the destination
("To") address associated with the message. The addMessagePart
method attaches a MessagePart
to the multipart
message.
Create utility methods for retrieving the application ID and managing the different UI screens.
// Return the application id, either from the // jad file or from a hardcoded value. String getApplicationID() { String applicationID = this.getAppProperty("Application-ID"); return applicationID == null ? APPLICATION_ID : applicationID; } // Upon capturing an image, show the compose screen void imageCaptured(byte[] imageData) { cameraScreen.stop(); resumeDisplay = sendScreen; Display.getDisplay(this).setCurrent(sendScreen); sendScreen.initializeComposeCanvas(imageData); } // Shows the screen capture camera void showCameraScreen() { resumeDisplay = cameraScreen; Display.getDisplay(this).setCurrent(cameraScreen); cameraScreen.start(); } // Shows the incoming message screen void showReceiveScreen() { resumeDisplay = receiveScreen; Display.getDisplay(this).setCurrent(receiveScreen); } void showSendScreen() { resumeDisplay = sendScreen; Display.getDisplay(this).setCurrent(sendScreen); } void resumeDisplay() { Display.getDisplay(this).setCurrent(resumeDisplay); } // Displays the info screen void showInfo(String messageString) { infoScreen.showInfo(messageString, Display.getDisplay(this)); } // Displays the error screen void showError(String messageString) { infoScreen.showError(messageString, Display.getDisplay(this)); }
Create methods
for starting and closing the message connection. The setMessageListener
method registers a MessageListener
object that
the platform can notify when a message has been received on this MessageConnection
.
// Closes the message connection when the applications // is stopped private void closeConnection() { if (messageConnection != null) { try { messageConnection.close(); } catch (IOException ioe) { // Ignore errors on shutdown } } } // Starts the message connection object private void startConnection(final MMSMIDlet mmsmidlet) { if (messageConnection == null) { // Open connection in a new thread so that it doesn't // block if a security permission request is shown new Thread() { public void run() { try { String mmsConnection = "mms://:" + getApplicationID(); messageConnection = (MessageConnection) Connector .open(mmsConnection); messageConnection.setMessageListener(mmsmidlet); } catch (IOException ioe) { showError("Exception while opening message connection: " + ioe.getMessage()); } } }.start(); } } }
Now that you have implemented the MIDlet main class, implement the UI elements.