For information about the design and functionality of the MIDlet, see section Design.
To create the MIDlet:
Create the APDUMIDlet.java
class file.
Import the required classes and packages.
import javax.microedition.io.Connector; import javax.microedition.apdu.APDUConnection; import javax.microedition.midlet.*; import javax.microedition.lcdui.*;
Set APDUMIDlet
to extend MIDlet
and implement CommandListener
and Runnable
. MIDlets use the CommandListener
interface to receive high-level UI events from the platform and
the Runnable
interface to execute threads.
public class APDUMIDlet extends MIDlet implements CommandListener, Runnable {
Create the required variables, the APDUMIDlet
class constructor, the MIDlet lifecycle methods, and the commandAction
method for implementing CommandListener
.
When you pass a request to the Connector.open
method to request an APDU
connection, you need the apdu:0;target=a0.00.00.00.62.03.01.0c.02.01
locator string . The string identifies the slot number (0
) and the card application identifier (a0.00.00.00.62.03.01.0c.02.01
).
private final String CardSlot0 = "apdu:0;target=a0.00.00.00.62.03.01.0c.02.01"; private APDUConnection cardConnection0; private Display display; private Form mainForm; private Command exitCommand, demoCommand, backCommand; private Form progressForm; /** Constructor for the APDUMIDlet. Creates required commands and the form. */ public APDUMIDlet() { exitCommand = new Command("Exit", Command.EXIT, 0); demoCommand = new Command("Demo", Command.SCREEN, 0); backCommand = new Command("Back", Command.BACK, 0); mainForm = new Form("APDU API Example"); mainForm.append(" Press Demo to open smartcard connection."); mainForm.addCommand(exitCommand); mainForm.addCommand(demoCommand); mainForm.setCommandListener(this); } public void startApp() { display = Display.getDisplay(this); display.setCurrent(mainForm); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == exitCommand) { notifyDestroyed(); } else if (c == demoCommand) { progressForm = new Form("Opening connection ..."); display.setCurrent(progressForm); Thread t = new Thread(this); t.start(); } else if (c == backCommand) { display.setCurrent(mainForm); } }
Use the Connector.open
method to pass a request to the Connector
class. The class returns an object that is able to exchange data
over the connection. Use the exchangeAPDU
method
to send a command to the card application and receive a response.
To close the APDU connection, call the close
method
on the connection.
public void run() { try { setProgress("Opening card at slot 0"); cardConnection0 = (APDUConnection) Connector.open(CardSlot0); setProgress("Exchanging APDUs with card slot 0"); byte[] response = cardConnection0.exchangeAPDU(kCardAPDU); progressForm.setTitle("Closing connection..."); progressForm.setTitle("Done."); /** Converts bytes to string format. */ String s = ""; for (int j = 0; j < response.length; j++) { int tmp = response[j]; if (tmp < 0) { tmp += 256; } String tmps = Integer.toHexString(tmp); if (tmps.length() == 1) { tmps = "0" + tmps; } s += tmps + " "; } Form g = new Form("Response APDU:"); g.append(s); g.addCommand(backCommand); g.setCommandListener(this); display.setCurrent(g); } catch (Exception e) { Form f = new Form("Exception"); f.append(e.toString()); f.addCommand(backCommand); f.setCommandListener(this); display.setCurrent(f); } finally { try { cardConnection0.close(); } catch (Throwable t) { } } } private void setProgress(String s) { StringItem si = new StringItem(null, s); si.setLayout(Item.LAYOUT_2 | Item.LAYOUT_NEWLINE_AFTER); progressForm.append(si); }
Define the APDU message as a byte array.
/** A sample APDU. */ private final byte[] kCardAPDU = // Select File EF_ID {(byte) 0x00, (byte) 0xA4, (byte) 0x08, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03}; // should return 01 90 00 }