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

Jay*_*Jay 7 java android nfc

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

恩智浦应用程序的NFC TagInfoNFC TagInfo都无法正确读取标签.


有效的设备:

  • Moto X Play(Android 6.0.1)
  • Moto G Play(Android 6.0.1)
  • 三星Galaxy S7(Android 7.0)
  • 三星Galaxy S8 - 英国型号(Android 7.0)
  • 像素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", ":(");
}
Run Code Online (Sandbox Code Playgroud)

当该方法IOException被抛出时,为-5(ERROR_CONNECT).connect()android.nfc.tech.BasicTagTechnologyerrorCode

有趣的是,对于有效的设备,由它公开的技术列表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连接到什么的混淆?

小智 0

在 Android 8+ 与 Android 6,7 上进行测试时,我发现IsoDep类存在类似问题

对我来说,关键是当我的应用程序位于前台并尝试读取/写入标签时,利用NfcAdapter.enableReaderMode实例方法关闭Android 设备上的主机卡模拟。

然后,我没有按照文档示例所示应用生命周期回调,而是遵循本问题所述的建议并执行了以下操作;

@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);
}
Run Code Online (Sandbox Code Playgroud)