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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 00:45:55