简体   繁体   中英

Connection error when reading Android NFC IsoDep tags

I have an app that reads various types of NFC tag. For years it's worked fine, but with newer Android devices a java.io.IOException is thrown consistently when scanning a particular type of tag. The tag in question has support for both Mifare Classic and ISO-DEP, but we're connecting using the IsoDep technology specifically.

Neither the NFC TagInfo or NFC TagInfo by NXP apps are able to read the tag without error either.


Devices that work:

  • Moto X Play (Android 6.0.1)
  • Moto G Play (Android 6.0.1)
  • Samsung Galaxy S7 (Android 7.0)
  • Samsung Galaxy S8 - UK model (Android 7.0)
  • Pixel 2 (Android 8.1)

Devices that fail:

  • Moto G5S (Android 7.1.1)
  • Moto Z2 Play (Android 7.1.1)
  • Moto E4 Plus (Android 7.1.1)
  • Huawei Honor 8 (Android 7.0)
  • LG K8 (Android 7.0)
  • LG K10 (Android 7.0)
  • Samsung Galaxy S8 - US model (Android 7.0)

The code needed to repro the issue is dead simple.

The NFC intent is received through foreground dispatch, and the following then runs in its own thread (with no other threads or NFC-related processing in between):

IsoDep isoDep = IsoDep.get(tag);

try {
    isoDep.connect();
}
catch (IOException e) {
    Log.e("NFC", ":(");
}

When the IOException is thrown by the connect() method within android.nfc.tech.BasicTagTechnology , the errorCode is -5 (ERROR_CONNECT).

Interestingly, for the devices that work, the tech list exposed by the Tag is as follows: android.nfc.tech.IsoDep, android.nfc.tech.NfcA

For devices that don't work the tech list is much longer, and contains duplicates: android.nfc.tech.IsoDep, android.nfc.tech.NfcA, android.nfc.tech.NfcA, android.nfc.tech.MifareClassic, android.nfc.tech.NdefFormattable

Finally, for devices that don't work, the following entry crops up in logcat: E/NxpNfcJni: Mifare Classic detected

Is it possible that with the extended NFC support offered by the more modern Android devices there is some confusion within the NFC system service about what TagTechnology to connect to?

I was seeing a similar issue with the IsoDep class when testing on Android 8+ vs Android 6,7

The key for me was to make use of the NfcAdapter.enableReaderMode instance method to turn off Host-Card-Emulation on the Android-Device while my App was in the foreground and trying to Read/Write Tags.

Then instead of applying the lifecycle callbacks as shown the Documentation Example , I followed the advice as noted for this Question and did the following;

@Override
public void onPause() {
    super.onPause();
    NfcAdapter.getDefaultAdapter(this).disableReaderMode(this);
}

@Override
public void onResume() {
    super.onResume();

    Bundle options = new Bundle();
    options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 500);

    adapter.enableReaderMode(
        this,
        new NfcAdapter.ReaderCallback() {
             @Override
             public void onTagDiscovered(final Tag tag) {
                 IsoDep isoDep = IsoDep.get(tag);
                 // Connect and perform rest of communication
             }
        },
        NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK,
        options
    ); 
}

@Override
public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
}

When a Tag supports multiple technology entries, each entry can be independently accessed using basic Tag technology api - tag.getTechList( );

Modify your code as follows:

    techList =  tag.getTechList();
    for (String tech : techList) {
        if (tech.equals("android.nfc.tech.IsoDep")) 
        {
            Log.i(TAG, "Tag Tech ISO DEP Found: " + tech );
            IsoDep isoDep = IsoDep.get(tag);
            try 
            {
                    isoDep.connect();
            }
            catch (IOException e) 
            {
                Log.e("NFC", ":(");
            }
        }
    }

Not all device will support MifareClassic Tag technology.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM