import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:nfc_manager/nfc_manager.dart'; import 'package:nfc_manager/ndef_record.dart'; import 'package:nfc_manager/nfc_manager_android.dart'; import 'package:nfc_manager/nfc_manager_ios.dart'; import 'package:nfc_manager_ndef/nfc_manager_ndef.dart'; class NfcTestPage extends StatefulWidget { const NfcTestPage({Key? key}) : super(key: key); @override _NfcTestPageState createState() => _NfcTestPageState(); } class _NfcTestPageState extends State { String _nfcData = '未扫描到标签。'; bool _scanning = false; void _safeSetState(String data) { if (!mounted) return; setState(() => _nfcData = data); } Future _startNfcSession() async { setState(() { _scanning = true; _nfcData = '扫描中...'; }); final available = await NfcManager.instance.isAvailable(); if (!available) { _safeSetState('此设备不支持 NFC'); setState(() => _scanning = false); return; } NfcManager.instance.startSession( onDiscovered: (NfcTag tag) async { String text = '未知'; try { final ndef = Ndef.from(tag); if (ndef == null) { _safeSetState('标签不支持 NDEF'); } else { final msg = ndef.cachedMessage; if (msg == null || msg.records.isEmpty) { _safeSetState('未找到任何 NDEF 记录'); } else { // 第一条记录 final record = msg.records.first; text = _parseTextRecord(record); _safeSetState('读取到文本: "$text"'); } } String uid = '未知'; try { if (Platform.isAndroid) { final nfcA = NfcAAndroid.from(tag); if (nfcA != null) { // 正确地通过 nfcA.tag.identifier 拿到 List final bytes = nfcA.tag.id; uid = bytes .map((b) => b.toRadixString(16).padLeft(2, '0')) .join(':') .toUpperCase(); } } else if (Platform.isIOS) { // iOS 平台,用 MiFareIos(对于大多数 ISO14443-A,也可以用 Iso7816Ios) final mifare = MiFareIos.from(tag); final bytes = mifare!.identifier; uid = bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(':').toUpperCase(); } } catch (e) { debugPrint('取 UID 错误: $e'); } finally { setState(() => _nfcData = '标签 UID: $uid' + '\n读取到文本: "$text"'); await NfcManager.instance.stopSession(); } } catch (e) { _safeSetState('解析时出错: $e'); } finally { await NfcManager.instance.stopSession(); if (mounted) setState(() => _scanning = false); } }, pollingOptions: {NfcPollingOption.iso14443}, ); } /// 解析一个 NDEF Text 记录的 payload,返回纯文本内容 String _parseTextRecord(NdefRecord record) { final payload = record.payload; if (payload.isEmpty) return ''; final statusByte = payload[0]; final langCodeLen = statusByte & 0x3F; // 文本数据开始的位置 final textBytes = payload.sublist(1 + langCodeLen); try { return utf8.decode(textBytes); // 默认 UTF‑8 } catch (e) { // 解码失败时,退回到直接展示 bytes return String.fromCharCodes(textBytes); } } @override void dispose() { NfcManager.instance.stopSession(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('NFC 测试')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ ElevatedButton( onPressed: _scanning ? null : _startNfcSession, child: Text(_scanning ? '扫描中...' : '开始扫描 NFC'), ), const SizedBox(height: 24), Expanded( child: SingleChildScrollView( child: Text(_nfcData, style: const TextStyle(fontSize: 16)), ), ), ], ), ), ); } }