使用nfc_manager写入Mifare Classic标签时遇PlatformException问题
问题
使用nfc_manager包开发NFC功能,针对Mifare Classic标签,在onTagDiscovered方法中调用写入方法时,执行到ndef.write(message)代码行,遇到PlatformException(invalid_parameter, Tag is not found, null, null)异常。该标签已通过NFC Tools应用验证为可写且为空。
相关代码:
Future<void> _ndefWrite(NfcTag tag) async { final ndef = Ndef.from(tag); final formattable = NdefFormatable.from(tag); final message = NdefMessage([ NdefRecord.createText('1'), // ID NdefRecord.createText('John'), // Name NdefRecord.createText('Doe'), // Surname ]); if (ndef != null) { if (!ndef.isWritable) { showErrorNotification( context: context, errorMessage: 'This tag is not writable.'); } final tech = MifareClassic.from(tag); if (tech == null) { log('Tag is not Mifare Classic'); } //define a list of access key A final listKeyDefault = [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ]; final dataKeyDefault = Uint8List.fromList(listKeyDefault); //define the data you want to write const String fullName = 'Sakhanya swartbooi'; //encode the the data as Uin8List final Uint8List data = utf8.encode(fullName) as Uint8List; try { tech?.authenticateSectorWithKeyA(sectorIndex: 2, key: dataKeyDefault); tech?.authenticateSectorWithKeyB(sectorIndex: 2, key: dataKeyDefault); await ndef.write(message); log('Successfully wrote to the Mifare Classic EV1 tag'); } on PlatformException catch (e) { log(e.message ?? 'Some error has occurred.'); } on Exception catch (e) { log(e.toString() ?? 'Some error has occurred.'); } } else if (formattable != null) { try { final tech = MifareClassic.from(tag); if (tech == null) { log('Tag is not Mifare Classic'); } //define a list of access key A final listKeyDefault = [ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ]; final dataKeyDefault = Uint8List.fromList(listKeyDefault); tech?.authenticateSectorWithKeyA(sectorIndex: 2, key: dataKeyDefault); tech?.authenticateSectorWithKeyB(sectorIndex: 2, key: dataKeyDefault); await formattable.format(message); } on PlatformException catch (e) { log(e.toString()); showErrorNotification( context: context, errorMessage: e.message.toString()); } } }
解决方法
1. 等待认证操作完成
authenticateSectorWithKeyA和authenticateSectorWithKeyB是异步方法,必须添加await确保认证完成后再执行写入操作,否则会因标签未完成认证就执行写入导致异常。
2. 匹配NDEF存储的扇区
Mifare Classic标签的NDEF数据默认存储在扇区0(包含块0-3),而非扇区2。自定义认证扇区2会导致NDEF写入时访问的扇区未被正确认证,进而触发错误。需将认证的扇区索引改为0。
3. 优化标签对象的有效性检查
在执行核心操作前,确保tech和ndef/formattable对象不为空,避免空安全隐患。
4. 修正后的代码
Future<void> _ndefWrite(NfcTag tag) async { final ndef = Ndef.from(tag); final formattable = NdefFormatable.from(tag); final tech = MifareClassic.from(tag); if (tech == null) { log('Tag is not Mifare Classic'); return; } final message = NdefMessage([ NdefRecord.createText('1'), // ID NdefRecord.createText('John'), // Name NdefRecord.createText('Doe'), // Surname ]); // 默认密钥 final defaultKey = Uint8List.fromList([0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); try { // 认证NDEF默认存储的扇区0 await tech.authenticateSectorWithKeyA(sectorIndex: 0, key: defaultKey); await tech.authenticateSectorWithKeyB(sectorIndex: 0, key: defaultKey); if (ndef != null) { if (!ndef.isWritable) { showErrorNotification(context: context, errorMessage: 'This tag is not writable.'); return; } await ndef.write(message); log('Successfully wrote to the Mifare Classic EV1 tag'); } else if (formattable != null) { await formattable.format(message); log('Successfully formatted and wrote to the Mifare Classic EV1 tag'); } else { showErrorNotification(context: context, errorMessage: 'Tag does not support NDEF.'); } } on PlatformException catch (e) { log('Platform error: ${e.message ?? 'Unknown error'}'); showErrorNotification(context: context, errorMessage: e.message ?? 'Failed to write tag.'); } catch (e) { log('Error: ${e.toString()}'); showErrorNotification(context: context, errorMessage: 'Unexpected error occurred.'); } }
额外注意事项
- 确保设备的NFC功能处于开启状态,且应用已获取NFC权限(在AndroidManifest.xml或Info.plist中配置)。
- 若标签已被自定义格式化,需确认NDEF存储的扇区与认证扇区一致,否则需调整扇区索引。
内容的提问来源于stack exchange,提问作者Convert.ToInt32
相关产品推荐
相关产品推荐

