我正在使用Ffltter 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代码 我认为问题在于当检测到代码中的空Tag时,它会变为null "Ndef.from(tag)" 但在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>

推荐答案

问题是空标记不是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标签,请try 检测NdeFormable标签,然后在那里格式化(并写入)您的Ndef消息.如果两种类型中的任何一种都不是,则失败.

Flutter相关问答推荐

Flutter:如何从Bottom Navigator中删除此内容

如何在Firebase项目中更改包名称和包ID

相同的Flutter 代码库,但Firebase登录适用于Web应用程序,但无法登录iOS应用程序

在创建肘部并使用冻结时,无法使用中的Copy With方法

FCM通知显示两次通知(&A)

如何将Will POP示波器转换为POP数据抖动的POP示波器

在Fighter中,我如何在窗口的顶部和底部排列Widget?

Flex ListView用于可滚动和响应的页面

为什么Spotify Auth API返回400,而";code_verier不正确?

Ffmpeg_kit_fltter:^6.0.3版权问题

如何确定Flutter 中的文本 colored颜色 ?

Flutter Android Google Sign-in error:ApiException:10在确认软件包名称、SHA-1 fingerprint 和设置同意页面后出现异常

从Firestore流式传输单个文档还是整个集合更好?

如何在flutter中更改showModalBottomSheet小部件中CheckboxListTile小部件的值?

Flutter 分析发现 Gitlab CI/CD 管道中的问题,但它在本地没有

如何在 flutter 中使用 tabbar 作为底部导航栏?

有没有办法为文本中的下划线创建自定义样式?

如何在 Flutter 中使用简写 IF 禁用单选按钮?

Firestore:缓存和读取数据

gridview 的所有按钮都应该在Flutter 中适合其父容器