| <html> |
| <body> |
| |
| <p>Provides classes that manage the NFC functionality.</p> |
| |
| <p>The NFC functionality is related to Near Field Communication.</p> |
| |
| <p>The NFC APIs let applications:</p> |
| <ul> |
| <li>Scan for remote NFC targets (NFC Tag or NFC Peer)</li> |
| <li>Transfer raw data to and from remote NFC targets (NFC Tags or NFC Peer)</li> |
| <li>Read/Write NDEF data from/to remote NFC targets (NFC Tags)</li> |
| <li>Establish LLCP connection with a remote NFC target (NFC Peer with LLCP support)</li> |
| <li>Exchange data with a remote NFC target through LLCP services (NFC Peer with LLCP support)</li> |
| <li>Be notified of transactions on the local Secure Element by an external NFC reader</li> |
| </ul> |
| |
| |
| <h1>Setting Up NFC</h1> |
| |
| <p> |
| Before an application can use the NFC feature, it needs to check if NFC is |
| supported on the device by getting an instance of the |
| {@link com.trustedlogic.trustednfc.android.NfcManager} class. |
| </p> |
| |
| <pre> |
| NfcManager mNfcManager = (NfcManager) getSystemService(Context.NFC_SERVICE); |
| if (mNfcManager == null) { |
| // Device does not support NFC |
| } |
| </pre> |
| |
| <p> |
| An application can ensure that NFC is enabled. |
| If not, an application with the needed permission can request that NFC be |
| enabled. |
| </p> |
| |
| <pre> |
| if (!mNfcManager.isEnabled) { |
| // NFC is currently disabled. |
| // Enable NFC. |
| mNfcManager.enable(); |
| } |
| </pre> |
| |
| <p> |
| Before using the card emulation mode, an application can ensure that a secure |
| element is selected ({@link com.trustedlogic.trustednfc.android.NfcManager#getSelectedSecureElement}). |
| If not, an application with the needed permission can recover the list of |
| available secure elements on the device |
| ({@link com.trustedlogic.trustednfc.android.NfcManager#getSecureElementList}) and select one |
| ({@link com.trustedlogic.trustednfc.android.NfcManager#selectSecureElement}). |
| </p> |
| |
| <p> |
| Before using the NFC feature, an application can configure the NFC device by |
| calling {@link com.trustedlogic.trustednfc.android.NfcManager#setProperties}. This function allows: |
| </p> |
| <ul> |
| <li>Enabling/disabling the NFC device capabilities (RF types, baudrates, |
| NFCIP-1 mode and role...)</li> |
| <li>Settings the NFCIP-1 general bytes and the LLCP link parameters</li> |
| </ul> |
| <p> |
| The setting properties can be customized according to the Device capabilities. |
| The next table give the minimal set of properties supported by the Device. |
| Depending on the implementation, the table may be completed. |
| </p> |
| <table> |
| <TR><TH> Property Name </TH><TH> Property Values </TH></TR> |
| <TR><TD> discovery.felica </TD><TD> <b>true</b>|false </TD></TR> |
| <TR><TD> discovery.iso14443A </TD><TD> <b>true</b>|false </TD></TR> |
| <TR><TD> discovery.iso14443B </TD><TD> <b>true</b>|false </TD></TR> |
| <TR><TD> discovery.iso15693 </TD><TD> <b>true</b>|false </TD></TR> |
| <TR><TD> discovery.nfcip </TD><TD> <b>true</b>|false </TD></TR> |
| <TR><TD> nfcip.baudrate </TD><TD> 106|212|424 </TD></TR> |
| <TR><TD> nfcip.generalbytes </TD><TD> </TD></TR> |
| <TR><TD> nfcip.mode </TD><TD> active|passive|<b>all</b> </TD></TR> |
| <TR><TD> nfcip.role </TD><TD> initiator|target|<b>both</b> </TD></TR> |
| <TR><TD> llcp.lto </TD><TD> <b>150</b> (0 to 255) </TD></TR> |
| <TR><TD> llcp.opt </TD><TD> <b>0</b> (0 to 3) </TD></TR> |
| <TR><TD> llcp.miu </TD><TD> <b>128</b> (128 to 2176) </TD></TR> |
| <TR><TD> llcp.wks </TD><TD> <b>1</b> (0 to 15) </TD></TR> |
| </table> |
| <p>(default values in bold)</p> |
| |
| |
| <h1>NFC Permissions</h1> |
| |
| <p> |
| To change the NFC service settings such as enabling the NFC targets |
| discovery or activating the secure element, an application must declare the |
| NFC_ADMIN permission. |
| </p> |
| <p> |
| To perform NFC raw communication with a remote NFC target in |
| Reader/Write Mode or Peer-to-Peer Mode, an application must declare the NFC_RAW |
| permission. |
| </p> |
| <p> |
| To receive NDEF message or Secure Element intents, an application must declare |
| the NFC_NOTIFY permission. |
| </p> |
| <p> |
| To receive the LLCP link intent and perform an LLCP communication with a remote NFC target, an application must |
| declare the NFC_LLCP permission. |
| </p> |
| |
| |
| <h1>NFC Usage</h1> |
| |
| <p> |
| The following code samples illustrate the APIs usage regarding the NFC service |
| use cases. |
| </p> |
| |
| <h2>Reader/Writer Mode NDEF message notification</h2> |
| |
| <p> |
| This code sample illustrates the NDEF message notification through an Intent declared in the manifest and a receiver implemented in the application. |
| </p> |
| <p>Main involved classes/methods:</p> |
| |
| <p>Manifest Example:</p> |
| <pre> |
| <receiver android:name=".NfcReaderDemoReceiver"> |
| <intent-filter> |
| <action android:name= "com.trustedlogic.trustednfc.android.action.NDEF_TAG_DISCOVERED"/> |
| </intent-filter> |
| </receiver> |
| </pre> |
| |
| <p>Receiver Example:</p> |
| <ul> |
| <li>{@link com.trustedlogic.trustednfc.android.NdefMessage}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#NDEF_TAG_DISCOVERED_ACTION}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#NDEF_MESSAGE_EXTRA}</li> |
| </ul> |
| <pre> |
| public class NdefMessageReceiverSample extends BroadcastReceiver { |
| public void onReceive(Context context, Intent intent) { |
| if (intent.getAction().equals(NfcManager.NDEF_TAG_DISCOVERERD_ACTION)) { |
| NdefMessage msg = intent.getParcelableExtra(NfcManager.NDEF_MESSAGE_EXTRA); |
| |
| /* Manage the NdefMessage received */ |
| } |
| </pre> |
| |
| <h2>Reader/Writer Mode raw exchange</h2> |
| |
| <p> |
| This code sample illustrates raw exchanges with a NFC target in Reader/Writer |
| mode. |
| </p> |
| <p>Main involved classes/methods:</p> |
| <ul> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#openTagConnection}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcTag}</li> |
| </ul> |
| |
| <pre> |
| public class TagReaderSample { |
| |
| /** The NFC manager to access NFC features */ |
| private NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE); |
| |
| private void runTagReader() { |
| NfcTag tag = null; |
| String type; |
| byte[] cmd = { 0x01, 0x02, 0x03 }; |
| byte[] res; |
| |
| while (true) { |
| try { |
| Log.i("NFC example", "Please wave in front of the tag"); |
| // Open a connection on next available tag |
| try { |
| tag = manager.openTagConnection(); |
| } catch (NfcException e) { |
| // TODO: Handle open failure |
| } |
| |
| // Look for a mifare 4k |
| type = tag.getType(); |
| if (type.equals("Mifare4K")) { |
| Log.i("NFC example", "Tag detected"); |
| tag.connect(); |
| // Ready to communicate, we can send transceive ! |
| res = tag.transceive(cmd); |
| } else { |
| Log.i("NFC example", "Unknown tag"); |
| } |
| } catch (IOException e) { |
| // TODO: Handle broken connection |
| } finally { |
| if (tag != null) { |
| tag.close(); |
| } |
| } |
| } |
| } |
| } |
| </pre> |
| |
| <h2>Peer-to-Peer Mode raw exchange</h2> |
| |
| <p> |
| This code sample illustrates raw exchanges with a NFC target in Peer-to-Peer |
| mode. |
| </p> |
| <p>Main involved classes/methods:</p> |
| <ul> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#openP2pConnection}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.P2pDevice}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.P2pInitiator}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.P2pTarget}</li> |
| </ul> |
| |
| <pre> |
| public class P2pSample { |
| |
| /** The NFC manager to access NFC features */ |
| private NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE); |
| |
| private void runP2p() { |
| P2pDevice deviceP2p; |
| P2pInitiator initiator; |
| P2pTarget target; |
| byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; |
| byte[] echo = new byte[data.length * 10]; |
| |
| try { |
| deviceP2p = manager.openP2pConnection(); |
| |
| if (deviceP2p.getMode() == P2pDevice.MODE_P2P_INITIATOR) { |
| target = new P2pTarget(deviceP2p); |
| // Connect to the detected P2P target |
| target.connect(); |
| // send data to the target |
| target.transceive(data); |
| // disconnect the connected target |
| target.disconnect(); |
| } else if (deviceP2p.getMode() == P2pDevice.MODE_P2P_TARGET) { |
| initiator = new P2pInitiator(deviceP2p); |
| //target in receive state |
| echo = initiator.receive(); |
| // send back the data received |
| initiator.send(echo); |
| } |
| } catch (IOException e0) { |
| |
| } catch (NfcException e1) { |
| |
| } |
| } |
| } |
| </pre> |
| |
| <h2>Peer-to-Peer Mode LLCP exchange</h2> |
| |
| <p> |
| This code sample illustrates how to get LLCP link state notification with the declaration of a Receiver in the manifest of the application and the implementation |
| of the receiver in the application. |
| </p> |
| <p>Manifest Example:</p> |
| <pre> |
| <receiver android:name=".LlcpModeReceiverSample"> |
| <intent-filter> |
| <action android:name= "com.trustedlogic.trustednfc.android.action.LLCP_LINK_STATE_CHANGED"/> |
| </intent-filter> |
| </receiver> |
| </pre> |
| |
| <p>Receiver Example:</p> |
| <ul> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#LLCP_LINK_STATE_CHANGED_ACTION}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#LLCP_LINK_STATE_CHANGED_EXTRA}</li> |
| </ul> |
| <pre> |
| public class LlcpModeReceiverSample extends BroadcastReceiver { |
| public void onReceive(Context context, Intent intent) { |
| |
| if (intent.getAction().equals(NfcManager.LLCP_LINK_STATE_CHANGED_ACTION)){ |
| byte[] aid = intent.getByteArrayExtra(NfcManager.LLCP_LINK_STATE_CHANGED_EXTRA); |
| /* Create an LLCP service or client and start an LLCP communication */ |
| } |
| } |
| </pre> |
| |
| |
| <p> |
| This code samples illustrate LLCP exchanges with a NFC Peer. |
| </p> |
| <p>Main involved classes/methods:</p> |
| <ul> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpSocket}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpConnectionlessSocket}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpServiceSocket}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.LlcpSocket}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.LlcpConnectionlessSocket}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.LlcpPacket}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.LlcpServiceSocket}</li> |
| </ul> |
| |
| <pre> |
| public class LlcpServerSample { |
| |
| /** The NFC manager to access NFC features */ |
| private NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE); |
| |
| private void runLlcpClient() { |
| LlcpSocket sock; |
| byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; |
| byte[] echo = new byte[data.length * 10]; |
| int length = 0; |
| |
| sock = manager.createLlcpSocket((short) 128, (byte) 2, 1024); |
| |
| // set a timeout in ms for connect request |
| sock.setConnectTimeout(10); |
| |
| try { |
| // Connect to remote service |
| // NOTE: could be sock.connect("com.trusted-logic.tnfc.testapp"); |
| sock.connect((byte) 0x10); |
| |
| // Send data |
| for (int i = 0; i < 10; i++) { |
| sock.send(data); |
| } |
| |
| // Receive echo |
| while (length < 10 * data.length) { |
| length += sock.receive(echo); |
| } |
| |
| } catch (IOException e) { |
| // TODO: Handle broken connection broken (link down, remote closure |
| // or connect rejected) or Timeout expired |
| } |
| } |
| } |
| </pre> |
| |
| <pre> |
| public class LlcpClientSample { |
| |
| /** The NFC manager to access NFC features */ |
| private NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE); |
| |
| private void runLlcpClient() { |
| LlcpSocket sock; |
| byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; |
| byte[] echo = new byte[data.length * 10]; |
| int length = 0; |
| |
| sock = manager.createLlcpSocket((short) 128, (byte) 2, 1024); |
| try { |
| // Connect to remote service |
| // NOTE: could be sock.connect("com.trusted-logic.tnfc.testapp"); |
| sock.connect((byte) 0x10); |
| |
| // Send data |
| for (int i = 0; i < 10; i++) { |
| sock.send(data); |
| } |
| |
| // Receive echo |
| while (length < 10 * data.length) { |
| length += sock.receive(echo); |
| } |
| |
| } catch (IOException e) { |
| // TODO: Handle broken connection broken (link down, remote closure |
| // or connect rejected) |
| } |
| } |
| } |
| </pre> |
| |
| <h2>Card Emulation Mode transaction notification</h2> |
| |
| <p> |
| This code sample illustrates how to get the card emulation notification with the declaration of a Receiver in the manifest of the application and the implementation |
| of the receiver in the application. |
| </p> |
| <p>Manifest Example:</p> |
| <pre> |
| <receiver android:name=".NfcReaderDemoReceiver"> |
| <intent-filter> |
| <action android:name= "com.trustedlogic.trustednfc.android.action.TRANSACTION_DETECTED"/> |
| </intent-filter> |
| </receiver> |
| </pre> |
| |
| <p>Receiver Example:</p> |
| <ul> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#TRANSACTION_DETECTED_ACTION}</li> |
| <li>{@link com.trustedlogic.trustednfc.android.NfcManager#AID_EXTRA}</li> |
| </ul> |
| <pre> |
| public class CardEmulationReceiverSample extends BroadcastReceiver { |
| public void onReceive(Context context, Intent intent) { |
| |
| if (intent.getAction().equals(NfcManager.TRANSACTION_DETECTED_ACTION)){ |
| byte[] aid = intent.getByteArrayExtra(NfcManager.AID_EXTRA); |
| /* Manage the AID: */ |
| /* For example start an activity related to this AID value or display a popup with the AID */ |
| } |
| } |
| </pre> |
| |
| |
| |
| <h1>Multiple Applications rules</h1> |
| |
| <p> |
| Several LLCP sockets can be created by a single application or by multiple |
| applications by calling {@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpSocket}, |
| {@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpConnectionlessSocket} or |
| {@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpServiceSocket}, provided the local SAP |
| numbers are differents. |
| </p> |
| |
| <p> |
| Only one application can open a raw connection by calling |
| {@link com.trustedlogic.trustednfc.android.NfcManager#openTagConnection} or |
| {@link com.trustedlogic.trustednfc.android.NfcManager#openP2pConnection}. |
| While this application has not closed or cancelled its connection, any other |
| application that attempts to open another raw connection will raise an |
| exception. |
| During an open connnection, the card emulation mode is always enabled and |
| applications are able to receive card emulation intents. |
| </p> |
| |
| <p> |
| When an application opens a tag connection by calling |
| {@link com.trustedlogic.trustednfc.android.NfcManager#openTagConnection}, this operation is exclusive, no NDEF message intent are |
| broadcast while the connection is not closed or canceled. |
| </p> |
| |
| <p> |
| When an application opens a peer-to-peer connection by calling |
| {@link com.trustedlogic.trustednfc.android.NfcManager#openP2pConnection}, this operation is exclusive, no LLCP intent are broadcast and LLCP sockets are |
| disabled while the connection is not closed or canceled. |
| </p> |
| |
| |
| <h1>NFC Tag types</h1> |
| |
| <p> |
| The {@link com.trustedlogic.trustednfc.android.NfcTag} type returned by |
| {@link com.trustedlogic.trustednfc.android.NfcTag#getType} indicates the set of |
| commands supported by the tag. These commands can be used in |
| {@link com.trustedlogic.trustednfc.android.NfcTag#transceive}. |
| </p> |
| |
| <TABLE BORDER="1"> |
| <TR><TH> Tag Type </TH><TH> Returned string </TH></TR> |
| <TR><TD> Jewel/Topaz </TD><TD> Jewel </TD></TR> |
| <TR><TD> Mifare UltraLight </TD><TD> MifareUL </TD></TR> |
| <TR><TD> Mifare Standard 1K </TD><TD> Mifare1K </TD></TR> |
| <TR><TD> Mifare Standard 4K </TD><TD> Mifare4K </TD></TR> |
| <TR><TD> Mifare DESFIRE </TD><TD> MifareDESFIRE </TD></TR> |
| <TR><TD> Felica </TD><TD> Felica </TD></TR> |
| <TR><TD> ISO14443-4 A or B </TD><TD> Iso14443 </TD></TR> |
| <TR><TD> ISO15693 </TD><TD> Iso15693 </TD></TR> |
| </TABLE> |
| |
| </body> |
| </html> |