繁体   English   中英

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

[英]Connection error when reading Android NFC IsoDep tags

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

NXP应用程序的NFC TagInfoNFC TagInfo都无法正确读取标签。


工作的设备:

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

失败的设备:

  • 摩托 G5S(安卓 7.1.1)
  • Moto Z2 Play (Android 7.1.1)
  • Moto E4 Plus (Android 7.1.1)
  • 华为荣耀8(安卓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", ":(");
}

android.nfc.tech.BasicTagTechnologyconnect()方法抛出IOExceptionerrorCode为 -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 存在一些混淆?

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

当一个 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 技术。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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