我有一个应用程序,可以读取各种类型的NFC标签.多年来它一直运行良好,但是对于较新的Android设备,java.io.IOException在扫描特定类型的标签时会一直抛出.有问题的标签支持Mifare Classic和ISO-DEP,但我们IsoDep专门使用该技术进行连接.
恩智浦应用程序的NFC TagInfo或NFC TagInfo都无法正确读取标签.
有效的设备:
失败的设备:
重现问题所需的代码很简单.
通过前台调度接收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)