簡體   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