Android NFC 未获得空的 NFC 标签

问题描述 投票:0回答:1

我正在使用 flutter nfc_manager 在 nfc 标签上写入。 它在 iOS 上运行得很好 但在 Android 中,当我尝试在空的 NFC 标签上写入时出现问题。 在具有现有数据的标签上写入工作正常。我该如何解决?

这是我的iOS代码

  Future<bool> _ndefWrite(NdefMessage ndefMessage) async {
    Completer<bool> completer = Completer<bool>();

    await NfcManager.instance.startSession(
      pollingOptions: {NfcPollingOption.iso14443, NfcPollingOption.iso15693},
      alertMessage: "NFC 태그를 스캔해주세요.",
      onDiscovered: (NfcTag tag) async {
        var ndef = Ndef.from(tag);
        if (ndef == null || !ndef.isWritable) {
          _errorMessage = "쓰기가 불가능한 NFC 태그입니다.";
          NfcManager.instance.stopSession(errorMessage: _errorMessage);
          completer.complete(false); // Use completer to complete with false
        } else {
          try {
            await ndef.write(ndefMessage);
            _alertMessage = "NFC 태그에 성공적으로 기록하였습니다.";
            NfcManager.instance.stopSession(alertMessage: _alertMessage);
            completer.complete(true); // Complete with true upon success
          } catch (error) {
            _errorMessage = error.toString();
            NfcManager.instance.stopSession(errorMessage: _errorMessage);
            completer.complete(false); // Complete with false on error
          }
        }
      },
      onError: (NfcError error) async {
        _errorMessage = error.message;
        NfcManager.instance.stopSession(errorMessage: _errorMessage);
        completer.complete(false); // Complete with false on error
      }
    );

    return completer.future.timeout(const Duration(seconds: 10), onTimeout: () {
      NfcManager.instance.stopSession(errorMessage: "NFC 스캔 시간 초과.");
      if (!completer.isCompleted) {
        completer.complete(false); // Complete with false only if not already completed
      }
      return false;
    });
  }

这是我的 Android 代码。 我认为问题在于,当检测到代码中的空标签时,它会变为 null “Ndef.from(标签)” 但在ios中它工作正常。

  Future<bool> _ndefWriteAndroid(NdefMessage ndefMessage) async {
    Completer<bool> completer = Completer<bool>();
    NFCDialog nfcDialog = NFCDialog(context: context, completer: completer);

    nfcDialog.show();
    await NfcManager.instance.startSession(
      onDiscovered: (NfcTag tag) async {
        Navigator.of(context, rootNavigator: true).pop();
        var ndef = Ndef.from(tag);
        if (ndef == null || !ndef.isWritable) {
          _errorMessage = "쓰기가 불가능한 NFC 태그입니다.";
          NfcManager.instance.stopSession(errorMessage: _errorMessage);
          completer.complete(false); // Use completer to complete with false
        } else {
          try {
            await ndef.write(ndefMessage);
            _alertMessage = "NFC 태그에 성공적으로 기록하였습니다.";
            NfcManager.instance.stopSession(alertMessage: _alertMessage);
            completer.complete(true); // Complete with true upon success
          } catch (error) {
            _errorMessage = error.toString();
            NfcManager.instance.stopSession(errorMessage: _errorMessage);
            completer.complete(false); // Complete with false on error
          }
        }
      },
    );

    return completer.future.timeout(const Duration(seconds: 10), onTimeout: () {
      Navigator.of(context, rootNavigator: true).pop();
      NfcManager.instance.stopSession(errorMessage: "NFC 스캔 시간 초과.");
      if (!completer.isCompleted) {
        completer.complete(false); // Complete with false only if not already completed
      }
      return false;
    });
  }

这是我在 AndroidManifest.xml 中的意图过滤器

    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    <intent-filter>
        <action android:name="android.nfc.action.TECH_DISCOVERED" />
    </intent-filter>
android flutter tags nfc
1个回答
0
投票

问题是空标签不是Ndef标签,Ndef标签必须至少有一个空TLV块。

在 Android 中,要检测能够存储 Ndef 消息的空标签,您需要查找 NdefFormatable 标签

所以你需要将代码中的逻辑重新安排为这样

var ndef = Ndef.from(tag);
if (ndef == null) {
   var ndefFormatable = NdefFormatable.from(tag);
   if (ndefFormatable != null) {
     // Format and write message in one operation.
     await ndefFormatable.format(ndefMessage);
    _alertMessage = "NFC Success message";
    NfcManager.instance.stopSession(alertMessage: _alertMessage);
    completer.complete(true); // Complete with true upon success
   } else {
     errorMessage = "Some error message";
     NfcManager.instance.stopSession(errorMessage: _errorMessage);
     completer.complete(false); // Use completer to complete with false
   }
} else if (!ndef.isWritable) {
  _errorMessage = "쓰기가 불가능한 NFC 태그입니다.";
  NfcManager.instance.stopSession(errorMessage: _errorMessage);
  completer.complete(false); // Use completer to complete with false
} else {
  try {
    await ndef.write(ndefMessage);
    _alertMessage = "NFC 태그에 성공적으로 기록하였습니다.";
    NfcManager.instance.stopSession(alertMessage: _alertMessage);
    completer.complete(true); // Complete with true upon success
  } catch (error) {
    _errorMessage = error.toString();
    NfcManager.instance.stopSession(errorMessage: _errorMessage);
    completer.complete(false); // Complete with false on error
  }
}

基本上,如果您没有检测到 Ndef 标签,请尝试检测 Ndeformatable 标签,然后在那里格式化(并写入)您的 Ndef 消息。如果不是任何一种类型,则失败。

© www.soinside.com 2019 - 2024. All rights reserved.