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
相关产品推荐
相关产品推荐

