阅读Android NFC IsoDep标签时出现连接错误

时间:2018-02-22 11:18:36

标签: java android nfc

我有一个应用程序,可以读取各种类型的NFC标签。多年来一直运行良好,但是对于较新的Android设备,在扫描特定类型的标签时会始终保持java.io.IOException。相关标签支持Mifare Classic和ISO-DEP,但我们专门使用IsoDep技术进行连接。

NFC TagInfoNFC TagInfo by NXP个应用都无法正确读取标记。

有效的设备:

  • Moto X Play(Android 6.0.1)
  • Moto G Play(Android 6.0.1)
  • 三星Galaxy S7(Android 7.0)
  • 三星Galaxy S8 - 英国型号(Android 7.0)
  • Pixel 2(Android 8.1)

失败的设备:

  • Moto G5S(Android 7.1.1)
  • Moto Z2 Play(Android 7.1.1)
  • Moto E4 Plus(Android 7.1.1)
  • 华为荣耀8(Android 7.0)
  • LG K8(Android 7.0)
  • LG K10(Android 7.0)
  • 三星Galaxy S8 - 美国型号(Android 7.0)

重复问题所需的代码很简单。

通过前台调度接收NFC意图,然后在其自己的线程中运行(没有其他线程或介于其间的NFC相关处理):

IsoDep isoDep = IsoDep.get(tag);

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

IOException方法connect()推出android.nfc.tech.BasicTagTechnology时,errorCode为-5(ERROR_CONNECT)。

有趣的是,对于有效的设备,Tag公开的技术列表如下: android.nfc.tech.IsoDep,android.nfc.tech.NfcA

对于不起作用的设备,技术列表要长得多,并且包含重复项: android.nfc.tech.IsoDep,android.nfc.tech.NfcA,android.nfc.tech.NfcA,android。 nfc.tech.MifareClassic,android.nfc.tech.NdefFormattable

最后,对于不起作用的设备,以下条目将在logcat中出现:E/NxpNfcJni: Mifare Classic detected

有可能通过更现代的Android设备提供的扩展NFC支持,NFC系统服务中存在一些关于TagTechnology要连接的内容的混淆吗?

2 个答案:

答案 0 :(得分:0)

在Android 8+上进行测试时, IsoDep 类出现了类似的问题 Android 6,7

对我来说,关键是利用NfcAdapter.enableReaderMode实例方法在我的应用程序位于前台时尝试在Android设备上关闭 Host-Card-Emulation 读/写标签。

然后,我没有像Documentation Example那样应用生命周期回调,而是按照针对此Question的建议进行了以下操作;

@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);
}

答案 1 :(得分:0)

当一个Tag支持多个技术条目时,可以使用基本的Tag技术api来独立访问每个条目——tag.getTechList();

修改你的代码如下:

    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", ":(");
            }
        }
    }

并非所有设备都支持 MifareClassic Tag 技术。