This section provides the source code for the SATSA MIDlet. For the complete Eclipse project ZIP file, see Forum Nokia.
The example includes the following classes:
package mmsmidlet; import java.io.*; import javax.microedition.io.*; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.wireless.messaging.*; // Main MIDlet class. It controls the user interface and the // MMS connection public class MMSMIDlet extends MIDlet implements MessageListener { 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 boolean closing; private Message nextMessage = null; public MMSMIDlet() {} 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(); } private synchronized void receive(Message incomingMessage) { if (receiveScreen==null) { receiveScreen = new ReceiveScreen(this); } receiveScreen.setMessage(incomingMessage); Display.getDisplay(this).setCurrent(receiveScreen); } 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(); } 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."); } } // 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) ); } // Closes the message connection when the applications // is stopped private void closeConnection() { closing = true; 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(); } } }
package mmsmidlet; import javax.microedition.lcdui.*; import javax.microedition.media.*; import javax.microedition.media.control.*; import java.io.IOException; // The CameraScreen class shows the live view // of the camera using the MMAPI and gives // commands to capture the contents of the camera class CameraScreen extends Canvas implements CommandListener { private final MMSMIDlet midlet; private final Command exitCommand; private Player player = null; private Command captureCommand = null; private VideoControl videoControl = null; private boolean active = false; CameraScreen(MMSMIDlet midlet) { this.midlet = midlet; // Builds the user interface exitCommand = new Command("Exit", Command.EXIT, 1); addCommand(exitCommand); captureCommand = new Command("Capture", Command.SCREEN, 1); addCommand(captureCommand); setCommandListener(this); } // Paint the canvas' background in black public void paint(Graphics g) { // black background g.setColor(0x00000000); g.fillRect(0, 0, getWidth(), getHeight()); } public void commandAction(Command c, Displayable d) { if (c == exitCommand) { midlet.exitApplication(); } else if (c == captureCommand) { captureImage(); } } public void keyPressed(int keyCode) { if (getGameAction(keyCode) == FIRE) { captureImage(); } } // Creates and starts the video player synchronized void start() { try { player = Manager.createPlayer("capture://video"); player.realize(); // Get VideoControl for the viewfinder videoControl = (VideoControl)player.getControl("VideoControl"); if (videoControl == null) { discardPlayer(); midlet.showError("Cannot get the video control.\n" +"Capture may not be supported."); player = null; } else { // Set up the viewfinder on the screen. videoControl.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this); int canvasWidth = getWidth(); int canvasHeight = getHeight(); int displayWidth = videoControl.getDisplayWidth(); int displayHeight = videoControl.getDisplayHeight(); int x = (canvasWidth - displayWidth) / 2; int y = (canvasHeight - displayHeight) / 2; videoControl.setDisplayLocation(x, y); player.start(); videoControl.setVisible(true); } } catch (IOException ioe) { discardPlayer(); midlet.showError("IOException: " + ioe.getMessage()); } catch (MediaException me) { midlet.showError("MediaException: " + me.getMessage()); } catch (SecurityException se) { midlet.showError("SecurityException: " + se.getMessage()); } } // Stops the video player synchronized void stop() { if (player != null) { try { videoControl.setVisible(false); player.stop(); } catch (MediaException me) { midlet.showError("MediaException: " + me.getMessage()); } active = false; } } // this method will discard the video player private void discardPlayer() { if (player != null) { player.deallocate(); player.close(); player = null; } videoControl = null; } // captures the image from the video player // in a separate thread private void captureImage() { if (player != null) { // Capture image in a new thread. new Thread() { public void run() { try { byte[] jpgImage = videoControl.getSnapshot("encoding=jpeg"); midlet.imageCaptured(jpgImage); discardPlayer(); } catch (MediaException me) { midlet.showError("MediaException: " + me.getMessage()); } catch (SecurityException se) { midlet.showError("SecurityException: " + se.getMessage()); } } }.start(); } } }
package mmsmidlet; import javax.microedition.lcdui.*; // Utility class used to show some information to the user class InfoScreen extends Alert { InfoScreen() { super("InfoScreen"); } void showInfo(String message, Display display) { setTitle("Info"); setType(AlertType.INFO); setTimeout(3000); setString(message); display.setCurrent(this); } void showError(String message, Display display) { setTitle("Error"); setType(AlertType.ERROR); setTimeout(5000); setString(message); display.setCurrent(this); } }
package mmsmidlet; import javax.microedition.lcdui.*; import javax.wireless.messaging.*; // Form used to display the contents of a received message class ReceiveScreen extends Form implements CommandListener { private String[] connections; private final MMSMIDlet midlet; private final Command commandClose = new Command("Close", Command.ITEM, 1); ReceiveScreen(MMSMIDlet midlet) { super(null); this.midlet = midlet; } public void setMessage(Message mmsMessage) { if (mmsMessage != null) { createForm(mmsMessage); } } public void commandAction(Command c, Displayable d) { if (c==commandClose) { midlet.resumeDisplay(); } } private void createForm(Message mmsMessage) { deleteAll(); setTitle("Received MMS Message"); if (mmsMessage instanceof MultipartMessage) { MultipartMessage multipartMessage = (MultipartMessage) mmsMessage; // Display message header. StringItem messageHeader = new StringItem(null, "From: " + mmsMessage.getAddress() + "\n" + "Sent: " + multipartMessage.getTimestamp().toString()); messageHeader.setLayout(Item.LAYOUT_NEWLINE_AFTER); append(messageHeader); MessagePart[] messageParts = multipartMessage.getMessageParts(); // Display all parts of the message. for (int i = 0; i < messageParts.length; i++) { MessagePart messagePart = messageParts[i]; String mimeType = messagePart.getMIMEType(); String contentLocation = messagePart.getContentLocation(); byte[] part = messagePart.getContent(); if (mimeType.equals("image/jpeg")) { // Message contains an image. Image image = Image.createImage(part, 0, part.length); ImageItem imageItem = new ImageItem(null, image, Item.LAYOUT_CENTER + Item.LAYOUT_NEWLINE_AFTER, contentLocation); append(imageItem); } if (mimeType.equals("text/plain")) { // Message contains text. StringItem stringItem = new StringItem(null, new String(part)); stringItem.setLayout(Item.LAYOUT_CENTER); append(stringItem); } // Unknown MIME-types are ignored } } addCommand(commandClose); setCommandListener(this); } }
package mmsmidlet; import java.io.*; import javax.microedition.lcdui.*; import javax.wireless.messaging.*; // This form displays the content of the captured image // and fields to add the recipient address and the // text of the message class SendScreen extends Form implements CommandListener { private final MMSMIDlet midlet; private final Command commandSend = new Command("Send", Command.ITEM, 1); private final Command commandBack = new Command("Back", Command.BACK, 0); private TextField messageText; private TextField recipientPhone; private byte[] messageImage; SendScreen(MMSMIDlet midlet) { super("MMS Message"); this.midlet = midlet; addCommand(commandSend); addCommand(commandBack); setCommandListener(this); } void initializeComposeCanvas(byte[] pngImage) { messageText = new TextField("Text: ", null, 256, TextField.ANY); recipientPhone = new TextField("To: ", null, 256,TextField.PHONENUMBER); messageImage = pngImage; Image tempImage = Image.createImage(pngImage, 0, pngImage.length); ImageItem imageItem = new ImageItem(null, tempImage, Item.LAYOUT_CENTER, null); deleteAll(); append(messageText); append(recipientPhone); append(imageItem); midlet.showSendScreen(); } public void commandAction(Command c, Displayable d) { if (c==commandBack) { midlet.showCameraScreen(); } if (c==commandSend) { sendMMS(); } } private void sendMMS() { String recipientAddress = "mms://" + recipientPhone.getString() + ":" + midlet.getApplicationID(); try { // get the byte content of the message and // the captured image byte[] textBytes = messageText.getString() .getBytes("UTF-8"); byte[] imageBytes = messageImage; // Create the message part containting the image // and give the appropriate MIME-type and id MessagePart imagePart= new MessagePart(imageBytes, 0, imageBytes.length, "image/jpeg", "id0", "snapshot image", null); // Create the message part containting the text // and give the appropriate MIME-type and id MessagePart textPart= new MessagePart(textBytes, 0, textBytes.length, "text/plain", "id1", "message text", "UTF-8"); midlet.showInfo("Sending message..."); midlet.sendMessage(recipientAddress, imagePart, textPart); } catch (UnsupportedEncodingException uee) { midlet.showError("Encoding not supported. " + uee.getMessage()); } catch (SizeExceededException see) { midlet.showError("Message part is too big. " + see.getMessage()); } } }