I'm trying to develop an application that uses Android NFC as smart card (Android 4.4.2 in HCE mode). I've read the guide about HCE on Android 4.4. I used the example along with the Android 4.4 SDK. But if try to read the HCE-emulated smart card from another Android NFC device (Android 4.3) with an NFC reader application, I see only these logs:
03-31 17:02:21.151: I/NFC-HCI(600): I'm P2P Active Initiator @ 424 kb/s
03-31 17:02:21.159: D/NFCJNI(600): Discovered P2P Target
03-31 17:02:21.159: D/NfcService(600): LLCP Activation message
03-31 17:02:21.183: I/NFC-HCI(600): I'm P2P Active Initiator @ 424 kb/s
03-31 17:02:21.190: I/NFCJNI(600): LLCP Link activated (LTO=150, MIU=128, OPTION=0x00, WKS=0x13)
03-31 17:02:21.190: I/NfcP2pLinkManager(600): LLCP activated
03-31 17:02:21.190: D/NfcP2pLinkManager(600): onP2pInRange()
[...]
03-31 17:02:22.144: I/NFCJNI(600): LLCP Link deactivated
03-31 17:02:22.144: D/NfcService(600): LLCP Link Deactivated message. Restart polling loop.
03-31 17:02:22.144: I/NfcP2pLinkManager(600): LLCP deactivated.
03-31 17:02:22.144: D/NfcP2pLinkManager(600): Debounce timeout
03-31 17:02:22.151: D/NfcP2pLinkManager(600): onP2pOutOfRange()
If I try, instead, to read a real smart card, it works as expected and I'm able to read the card:
TagID (hex): c4 2a 29 c8
TagID (dec): 3291097544
Technologies: MifareClassic, NfcA,NdefFormatable
Mifare Classic type: Classic
Mifare size: 1024 btes
Mifare sectors: 16
Mifare blocks: 64
I've read this thread but my knowledge in this regard are very few.
Simple answer: what you are trying to do is not possible.
The problem here is that two Android devices will communicate in peer-to-peer mode by default (even if one or both devices support host card emulation). Once an Android device successfully communicates in peer-to-peer mode, it won't try to communicate in reader/writer mode. Consequently, your device with the reader app won't detect the HCE-emulated "card" of the other device.
In order to permit the Android HCE-emulated card to be visible to the second device with the reader app, that second device would need to disable its peer-to-peer mode capabilities and be active only in reader/writer mode. That's were the thread you were refereing to (Android : How to change NFC protocol priority?) comes in. By using the reader mode API, more specifically the enableReaderMode
method of the NfcAdapter
with the flags FLAG_READER_NFC_A
, FLAG_READER_NFC_B
(and optionally FLAG_READER_SKIP_NDEF_CHECK
), you can force the (reader side!!!) Android device to act only in reader/writer mode and to disable peer-to-peer mode:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback() {
public void onTagDiscovered(Tag tag) {
// TODO: access tag...
}
},
NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_NFC_B | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);
Unfortunately, this API is only available on Android 4.4 and later. So with an Android 4.3 device, you have no means to disable peer-to-peer mode and therefore can't communicate with an Android HCE "card".