Flutter nfc_manager安卓写入空NFC标签失败(iOS正常)求修复方案
问题解决步骤
核心原因
Android系统对空NFC标签的识别逻辑和iOS不同:空标签尚未被格式化为NDEF规范,Ndef.from(tag)会返回null;而iOS会自动处理未格式化标签的兼容性,直接允许写入。
解决方案
1. 完善AndroidManifest配置
原配置缺少NDEF相关过滤规则,需补充NDEF_DISCOVERED和TAG_DISCOVERED,同时为TECH_DISCOVERED指定支持的NFC技术类型:
<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.NDEF_DISCOVERED"/> <action android:name="android.nfc.action.TAG_DISCOVERED"/> <action android:name="android.nfc.action.TECH_DISCOVERED"/> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter"/>
在res/xml/目录下创建nfc_tech_filter.xml文件,添加支持的NFC技术:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NdefFormatable</tech> <tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.MifareClassic</tech> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
2. 修改Android端写入逻辑,兼容未格式化标签
当Ndef.from(tag)返回null时,尝试通过NdefFormatable.from(tag)格式化标签后再写入数据:
Future<bool> _ndefWriteAndroid(NdefMessage ndefMessage) async { Completer<bool> completer = Completer<bool>(); NFCDialog nfcDialog = NFCDialog(context: context, completer: completer); nfcDialog.show(); await NfcManager.instance.startSession( // 补充扫描选项,和iOS保持一致的支持范围 pollingOptions: {NfcPollingOption.iso14443, NfcPollingOption.iso15693}, onDiscovered: (NfcTag tag) async { Navigator.of(context, rootNavigator: true).pop(); var ndef = Ndef.from(tag); if (ndef != null) { // 已格式化的NDEF标签,直接写入 if (!ndef.isWritable) { _errorMessage = "쓰기가 불가능한 NFC 태그입니다."; NfcManager.instance.stopSession(errorMessage: _errorMessage); completer.complete(false); } else { try { await ndef.write(ndefMessage); _alertMessage = "NFC 태그에 성공적으로 기록하였습니다."; NfcManager.instance.stopSession(alertMessage: _alertMessage); completer.complete(true); } catch (error) { _errorMessage = error.toString(); NfcManager.instance.stopSession(errorMessage: _errorMessage); completer.complete(false); } } } else { // 未格式化的标签,先格式化为NDEF再写入 var ndefFormatable = NdefFormatable.from(tag); if (ndefFormatable == null) { _errorMessage = "지원하지 않는 NFC 태그입니다."; NfcManager.instance.stopSession(errorMessage: _errorMessage); completer.complete(false); } else { try { await ndefFormatable.format(ndefMessage); _alertMessage = "NFC 태그에 성공적으로 기록하였습니다."; NfcManager.instance.stopSession(alertMessage: _alertMessage); completer.complete(true); } catch (error) { _errorMessage = error.toString(); NfcManager.instance.stopSession(errorMessage: _errorMessage); completer.complete(false); } } } }, ); 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); } return false; }); }
3. 关键说明
- Android要求未格式化的NFC标签必须先通过
NdefFormatable格式化,才能写入NDEF数据,这一步iOS会自动完成,无需额外处理。 - 补充
pollingOptions可确保Android设备扫描范围和iOS一致,覆盖更多类型的NFC标签。
内容的提问来源于stack exchange,提问作者code_San
相关产品推荐
相关产品推荐

