URLWriter.java

/*
 * Copyright © 2011 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.
 */

/**
 * @author Gerald Madlmayr (original) & Forum Nokia
 * @version 1.2
 *
 * MIDlet that writes a URL to an external NDEF tag
 */

package com.nokia.example;

// Classes for contactless communication
import java.io.IOException;
import javax.microedition.contactless.ContactlessException;
import javax.microedition.contactless.DiscoveryManager;
import javax.microedition.contactless.TargetListener;
import javax.microedition.contactless.TargetProperties;
import javax.microedition.contactless.TargetType;

// Classes for NDEF targets
import javax.microedition.contactless.ndef.NDEFMessage;
import javax.microedition.contactless.ndef.NDEFRecord;
import javax.microedition.contactless.ndef.NDEFRecordType;
import javax.microedition.contactless.ndef.NDEFTagConnection;
import javax.microedition.io.Connector;

// Classes for UI
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;

import javax.microedition.midlet.*;

public class URLWriter
        extends MIDlet
        implements TargetListener, CommandListener {

    // Global variables for the UI
    private Command exitCommand;
    private Form form;

    public URLWriter() {

        exitCommand = new Command("Exit", Command.EXIT, 1);
        form = new Form("URLWriter");

        form.addCommand(exitCommand);
        form.setCommandListener(this);
        form.append("Touch tag to write URL: \"www.developer.nokia.com\"");

        // Determine the contactless target types supported by the device
        TargetType[] supportedTargetTypes = DiscoveryManager.getSupportedTargetTypes();

        // Check if the NDEF_TAG type is supported by the device,
        // and, if it is, register TargetListener for it
        for (int i=0; i<supportedTargetTypes.length; i++) {
            if (supportedTargetTypes[i].equals(TargetType.NDEF_TAG)) {
                // Register TargetListener (this) for NDEF targets
                try {
                    DiscoveryManager dm = DiscoveryManager.getInstance();
                    dm.addTargetListener(this, TargetType.NDEF_TAG);
                } catch (SecurityException se) {
                    displayAlert("Unable to register TargetListener: " + se.toString(), AlertType.ERROR);
                } catch (ContactlessException ce) {
                    displayAlert("Unable to register TargetListener: " + ce.toString(), AlertType.ERROR);
                } catch (IllegalStateException ise) {
                    displayAlert("Unable to register TargetListener: " + ise.toString(), AlertType.ERROR);
                } catch (NullPointerException npe) {
                    displayAlert("Unable to register TargetListener: " + npe.toString(), AlertType.ERROR);
                }
                // Break the loop, since a matching target type has been found
                break;
            }
        }

    }

    public void startApp() {
        Display.getDisplay(this).setCurrent(form);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    /**
     * Implements the callback function of TargetListener
     * @param targetProperties: Array of targets found by the device
     */
    public void targetDetected(TargetProperties[] targetProperties) {

        // In case no targets are found, exit the method
        if (targetProperties.length == 0) {
            return;
        }

        // NDEF connection for write operation
        NDEFTagConnection ndconn = getNDEFTAGConnection(targetProperties);
        try {

            // Header byte: open bookmark in browser
            byte[] headerByte = {0x00};

            // Payload text: URL as a byte array
            byte[] urlBytes = "http://www.developer.nokia.com/".getBytes();

            // Create an NDEF record of type urn:nfc:wkt:U (a URI record)
            // using the NFC Forum Record Type Description syntax
            NDEFRecord r = new NDEFRecord(new NDEFRecordType(NDEFRecordType.NFC_FORUM_RTD, "urn:nfc:wkt:U"), null, null);

            // Append payload manually
            r.appendPayload(headerByte);
            r.appendPayload(urlBytes);

            // Create record array and add record
            NDEFRecord[] myRecArray = new NDEFRecord[]{r};

            // Generate a message out of the array
            NDEFMessage myMessage = new NDEFMessage(myRecArray);

            // Write message to tag
            ndconn.writeNDEF(myMessage);

            displayAlert("Information written", AlertType.INFO);

        } catch (IOException io) {
            displayAlert("Writing failed, please try again.", AlertType.ERROR);
        } catch (ContactlessException io) {
            displayAlert("ContactlessException during writeNDEF(): " + io.toString(), AlertType.ERROR);
        } catch (Exception e) {
            displayAlert("Exception: " + e.toString(), AlertType.ERROR);
        } // In case of an exception, close connection properly
        finally {
            // Close connection again
            if (ndconn != null) {
                try {
                    ndconn.close();
                } catch (IOException ex) {
                    displayAlert("IOException during close(): " + ex.toString(), AlertType.ERROR);
                }
            }
        }

    }

    private NDEFTagConnection getNDEFTAGConnection(TargetProperties[] tProp) {
        for (int j = 0; j < tProp.length; j++) {
            Class[] connections = tProp[j].getConnectionNames();
            if (connections != null) {
                for (int i = 0; i < connections.length; i++) {
                    if (connections[i].getName().equals(
                            "javax.microedition.contactless.ndef.NDEFTagConnection")) {
                        try {
                            return (NDEFTagConnection) Connector.open(tProp[j].getUrl(connections[i]));
                        } catch (Exception e) {
                            displayAlert("Error writing NDEF: " + e.toString(), AlertType.ERROR);
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * Implements the callback function of CommandListener
     * @param command: Command given
     * @param displayable: Associated Displayable object
     */
    public void commandAction(Command command, Displayable displayable) {
        if (command == exitCommand) {
            DiscoveryManager dm = DiscoveryManager.getInstance();
            dm.removeTargetListener(this, TargetType.NDEF_TAG);
            destroyApp(false);
            notifyDestroyed();
        }
    }

    private void displayAlert(String error, AlertType type) {
        Alert err = new Alert(form.getTitle(), error, null, type);
        Display.getDisplay(this).setCurrent(err, form);
    }
}