I have realized situation when one android device as an NFC reader communicates with an HCE application installed on another android device. But there were two problems:
- It works only when android version of device that acts as an NFC reader is 4.4 and above.
- Communication between phones was failing and recovering all the time (reason of deactivation is DEACTIVATION_LINK_LOSS).
Here is the main class of my app for NFC reader:
public class ReadingCardActivity extends Activity {
// list of NFC technologies detected:
private final String[][] techList = new String[][]{
new String[]{
NfcA.class.getName(),
NfcB.class.getName(),
NfcF.class.getName(),
NfcV.class.getName(),
IsoDep.class.getName(),
MifareClassic.class.getName(),
MifareUltralight.class.getName(),
Ndef.class.getName()
}
};
TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tag);
tv = (TextView) findViewById(R.id.tv);
tv.setMovementMethod(new ScrollingMovementMethod());
}
@Override
protected void onResume() {
super.onResume();
// creating pending intent:
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
// creating intent receiver for NFC events:
IntentFilter filter = new IntentFilter();
filter.addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
filter.addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filter.addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
// enabling foreground dispatch for getting intent from NFC event:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, new IntentFilter[]{filter}, this.techList);
}
@Override
protected void onPause() {
super.onPause();
// disabling foreground dispatch:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
nfcAdapter.disableForegroundDispatch(this);
}
@Override
protected void onNewIntent(Intent intent) {
if (intent.getAction().equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
if (intent.getAction() != null) {
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
try {
IsoDep iso = IsoDep.get(tagFromIntent);
iso.connect();
tv.setText(tv.getText() + "\nResponse from card: " + Utils.byteArrayToHexString(selectAID(iso)));
iso.close();
} catch (Exception ex) {
tv.setText(tv.getText() + "\nException: " + ex.toString());
}
}
}
}
public byte[] selectAID(IsoDep iso) throws Exception {
byte[] wakeUpCommand = {(byte) 0x00, (byte) 0xA4, (byte) 0x04,(byte) 0x00, (byte) 0x08,
(byte) 0x4C, (byte) 0x65, (byte) 0x6C,(byte) 0x61,
(byte) 0x6E, (byte) 0x74, (byte) 0x6F, (byte) 0x73,
(byte) 0x00};
return iso.transceive(wakeUpCommand);
}
}
And here is my service in HCE application:
@Override
public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
sendResult("Terminal sent apdu " + Utils.byteArrayToHexString(apdu));
byte[] response = Hex.decodeHex(SUCCESSFUL_RESPONSE.toCharArray());
return response;
}
You might also want to see my apduservice.xml file to see my AID number:
<?xml version="1.0" encoding="utf-8"?>
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:requireDeviceUnlock="false">
<aid-group android:category="other">
<aid-filter android:name="4C656C616E746F73"/>
</aid-group>
</host-apdu-service>
It's my onDeactivated
method in HCE application:
@Override
public void onDeactivated(int reason) {
switch (reason) {
case DEACTIVATION_LINK_LOSS:
sendResult("\nDeactivation was due to the NFC link being lost.\n");
break;
case DEACTIVATION_DESELECTED:
sendResult("\nDeactivation was due to a different AID being selected.\n");
break;
}
}
And output of HCE application:
+---------------------------------------------+
Terminal sent apdu 00A40400084C656C616E746F7300
Deactivation was due to the NFC link being lost.
Terminal sent apdu 00A40400084C656C616E746F7300
Deactivation was due to the NFC link being lost.
Terminal sent apdu 00A40400084C656C616E746F7300
Deactivation was due to the NFC link being lost.
+---------------------------------------------+
Can anyone help me with these problems?