MMSMIDlet.java

/**
 * Copyright (c) 2012 Nokia Corporation. All rights reserved.
 * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation.
 * Oracle and Java are trademarks or registered trademarks of Oracle and/or its
 * affiliates. Other product and company names mentioned herein may be trademarks
 * or trade names of their respective owners.
 * See LICENSE.TXT for license information.
 */

package com.nokia.example.mmsmidlet;

import com.nokia.mid.ui.orientation.Orientation;
import com.nokia.mid.ui.orientation.OrientationListener;
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.*;

// Main MIDlet class.
// This controls the user interface and the MMS connection
public class MMSMIDlet extends MIDlet implements MessageListener, OrientationListener {

    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() {
    }

    public void startApp() {

        /**
         * Registers the orientation listener. Applications that need
         * information about events related to display orientation changes need
         * to register with Orientation to get notifications of the events.
         */
        Orientation.addOrientationListener(this);


        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);
    }

    /**
     * The Callback is not working properly on some devices and is under
     * investigation. If the operator of the recipient does not support
     * Java MMS, an MMS sent to a Java application will end up in
     * the destination phone's Inbox instead of being dispatched to the
     * destination phone's Java application.
     * See the Wireless Messaging API (WMA) for Java™ 2 Micro Edition
     * Appendix D for more details.
     */
    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 {

            if (messageConnection != null) {
                // 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());
                        } catch (SecurityException se) {
                            showError("SecurityException: " + se.getMessage());
                        }
                    }
                }.start();
            } else {
                showError("Sending failed");
            }
        } 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() {

        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();
        }
    }

    /**
     * Orientation is supported for Java Runtime 2.0.0 for Series 40 onwards.
     * Called when display's orientation has changed.
     */
    public void displayOrientationChanged(int newDisplayOrientation) {

        // No Orientation when in camera screen
        if (Display.getDisplay(this).getCurrent() == cameraScreen) {
            return;
        }

        /**
         * Change MIDlet UI orientation to portrait
         */
        Orientation.setAppOrientation(newDisplayOrientation);

    }
}