qhd-prevention-flutter/lib/customWidget/nfc_test_page.dart

144 lines
4.4 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<NfcTestPage> {
String _nfcData = '未扫描到标签。';
bool _scanning = false;
void _safeSetState(String data) {
if (!mounted) return;
setState(() => _nfcData = data);
}
Future<void> _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<int>
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); // 默认 UTF8
} 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)),
),
),
],
),
),
);
}
}