You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter使用nfc_manager包读写NFC卡时ndef空值及异常问题求助

解决Flutter nfc_manager多次写入后NFC读写失效、ndef为null的问题

问题核心

多次执行NFC写入操作后,Ndef.from(tag)返回null,触发"Tag is not ndef writable."提示,后续所有NFC读写操作失效,必须重启设备才能恢复。本质是Session管理不严谨导致的资源未释放、Session冲突问题。


解决方案

1. 修复Session管理逻辑

原代码中Session的停止和启动存在异步处理漏洞,需确保Session的启停操作严谨,避免残留未释放的资源:

  • 用try-catch包裹stopSession,防止重复停止Session抛出异常
  • 增加状态变量,禁止短时间内重复启动Session,避免冲突

2. 优化NDEF标签处理流程

  • 区分"标签不支持NDEF"和"标签不可写"两种场景,避免错误提示混淆
  • 确保任何分支下都正确停止Session,释放NFC资源
  • 不要吞掉读取操作的异常,保留日志便于排查问题

3. 修改后的代码示例

// 新增状态变量,防止重复触发NFC操作
bool _isNfcProcessing = false;

Future<void> handleNfcOperation() async {
  if (_isNfcProcessing) return;
  _isNfcProcessing = true;

  try {
    if (await NfcManager.instance.isAvailable()) {
      // 确保前一个Session已停止,捕获可能的异常
      try {
        await NfcManager.instance.stopSession();
      } catch (e) {
        print('停止Session异常: $e');
      }
      
      await NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async {
        bool sessionStopped = false;
        try {
          var ndef = Ndef.from(tag);
          
          // 区分标签不支持NDEF的情况
          if (ndef == null) {
            await NfcManager.instance.stopSession(errorMessage: "标签不支持NDEF格式");
            sessionStopped = true;
            showDialog(
              context: context,
              builder: (_) => BaseAlertDialog(
                title: "提示",
                content: "标签不支持NDEF格式",
                backgroundColor: Colors.red.shade300,
                yesOnPressed: () {
                  _isPrintPressed = false;
                  Navigator.pop(context);
                },
                yes: "OK",
              )
            );
            return;
          }

          // 标签支持NDEF但不可写的情况
          if (!ndef.isWritable) {
            await NfcManager.instance.stopSession(errorMessage: "标签不可写入");
            sessionStopped = true;
            showDialog(
              context: context,
              builder: (_) => BaseAlertDialog(
                title: "提示",
                content: "标签不可写入",
                backgroundColor: Colors.red.shade300,
                yesOnPressed: () {
                  _isPrintPressed = false;
                  Navigator.pop(context);
                },
                yes: "OK",
              )
            );
            return;
          }

          NdefMessage ndefMessage;
          try {
            ndefMessage = await ndef.read();
          } catch (readError) {
            print('读取标签异常: $readError');
            // 读取失败不直接终止,按需继续后续逻辑
          }

          if (await _validateTag(ndefMessage) || ndefMessage == null) {
            // 执行你的写入/业务操作
            // ...

            // 操作完成后主动停止Session
            await NfcManager.instance.stopSession();
            sessionStopped = true;
          }
        } finally {
          // 确保无论分支走向如何,都停止Session并重置状态
          if (!sessionStopped) {
            await NfcManager.instance.stopSession();
          }
          _isNfcProcessing = false;
        }
      });
    } else {
      print("NFC功能不可用");
      _isNfcProcessing = false;
    }
  } catch (e) {
    print('NFC操作整体异常: $e');
    _isNfcProcessing = false;
  }
}

额外建议

  • 升级nfc_manager到最新版本,官方可能已修复Session管理相关的已知bug
  • 测试不同型号的NFC标签,排除特定标签兼容性问题
  • 若问题仍存在,可尝试在操作完成后延迟100-200ms再停止Session,给硬件足够的资源释放时间

内容的提问来源于stack exchange,提问作者Kolitha Sandirigama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:40:44