Flutter NFC读写插件ndef的使用
Flutter NFC读写插件ndef的使用
ndef
是一个用于解码和编码NDEF记录的Dart库,支持多种类型(按类型名称格式分组),包括:
-
NFC Well-known Records (TNF 1 /
urn:nfc:wkt:
),包含:- 文本 (class
T
) - URI带有知名前缀 (class
U
) - 数字签名 (class
Sig
) - 智能海报 (class
Sp
),包括子记录:- 动作 (class
act
) - 大小 (class
s
) - 类型 (class
t
)
- 动作 (class
- 连接切换 (class
Hr/Hs/Hm/Hi/Hc/ac/cr
)
- 文本 (class
-
Media Records (TNF 2, 包含MIME数据),包含:
- 蓝牙简易配对 (class
application/vnd.bluetooth.ep.oob
) - 蓝牙低能耗 (class
application/vnd.bluetooth.le.oob
)
- 蓝牙简易配对 (class
-
Absolute URI Records (TNF 3)
-
External Records (TNF 4 /
urn:nfc:ext:
),包含:- Android应用程序记录 (class
android.com:pkg
)
- Android应用程序记录 (class
注意:此库仍在积极开发中,可能会出现破坏性API更改和功能故障。欢迎提交问题和拉取请求,特别是在以下方面:
- Bug修复
- 支持新的记录类型
使用示例
编码与解码NDEF记录
import 'package:ndef/ndef.dart' as ndef;
void main() {
// 编码
var uriRecord = ndef.UriRecord.fromString("https://github.com/nfcim/ndef");
var textRecord = ndef.TextRecord(text: "Hello");
var encodedUriRecord = uriRecord.encode().toHexString(); /// 编码单个记录,并使用Uint8List上的扩展方法
var encodedAllRecords = ndef.encodeNdefMessage([uriRecord, textRecord]).toHexString(); // 编码多个记录为一条消息
// 解码
var encodedTextRecord = "d1010f5402656e48656c6c6f20576f726c6421";
var decodedRecords = ndef.decodeRawNdefMessage(encodedTextRecord.toBytes());
assert(decodedRecords.length == 1);
if (decodedRecords[0] is ndef.TextRecord) {
assert(decodedRecords[0].text == "Hello");
} else {
// 我们不会到这里
}
// 数据绑定(通过实现payload作为动态getter/setter)
var origPayload = uriRecord.payload!;
print(origPayload.toHexString());
uriRecord.content = "github.com/nfcim/flutter_nfc_kit";
print(uriRecord.payload!.toHexString()); // 已更改
uriRecord.payload = origPayload;
print(uriRecord.content); // 变回原来
// 部分解码记录
var partiallyDecodedUrlRecord = ndef.decodePartialNdefMessage(
ndef.TypeNameFormat.nfcWellKnown, utf8.encode("U"), origPayload,
id: Uint8List.fromList([0x1, 0x2]));
}
完整示例代码
import 'dart:convert';
import 'dart:typed_data';
import 'package:ndef/ndef.dart' as ndef;
import 'package:ndef/utilities.dart';
void main() {
var encodedUrlRecord =
"91011655046769746875622e636f6d2f6e6663696d2f6e64656651010b55046769746875622e636f6d";
var urlRecords = [
ndef.UriRecord.fromString("https://github.com/nfcim/ndef"),
ndef.UriRecord.fromString("https://github.com")
];
// 解码完整的NDEF消息(记录的连接)
var decodedUrlRecords = ndef.decodeRawNdefMessage(encodedUrlRecord.toBytes());
assert(urlRecords.length == decodedUrlRecords.length);
for (int i = 0; i < urlRecords.length; i++) {
var raw = urlRecords[i];
var decoded = decodedUrlRecords[i];
assert(decoded is ndef.UriRecord);
assert((decoded as ndef.UriRecord).uri == raw.uri);
print((decoded as ndef.UriRecord).toString());
}
// 修改记录通过数据绑定
var origPayload = urlRecords[0].payload!;
print('===================');
print('original payload: ${origPayload.toHexString()}');
print('original uri: ${urlRecords[0].uri}');
// 更改URI
print('===================');
urlRecords[0].content =
'github.com/nfcim/flutter_nfc_kit'; // 这也是我们很棒的库,快来看看!
print(
'payload after change content: ${urlRecords[0].payload!.toHexString()}'); // 在调用时编码
print('uri after change content: ${urlRecords[0].uri}');
// 通过使用payload恢复更改
print('===================');
urlRecords[0].payload = origPayload; // 在调用时解码
print('payload after changed back: ${urlRecords[0].payload!.toHexString()}');
print('uri after changed back: ${urlRecords[0].uri}');
// 再次编码为消息(也规范MB & MF字段)
var encodedAgain = ndef.encodeNdefMessage(urlRecords);
assert(encodedAgain.toHexString() == encodedUrlRecord);
print('encoded single record: ${urlRecords[0].encode().toHexString()}');
// 也可以分别提供id、type和payload进行解码(通常来自手机API)
print('===================');
var partiallyDecodedUrlRecord = ndef.decodePartialNdefMessage(
ndef.TypeNameFormat.nfcWellKnown, utf8.encode("U"), origPayload,
id: Uint8List.fromList([0x1, 0x2]));
assert(partiallyDecodedUrlRecord is ndef.UriRecord);
print(
'partially decoded record: ${partiallyDecodedUrlRecord as ndef.UriRecord}');
}
希望这能帮助您更好地理解和使用ndef
库。如果您有任何问题或需要进一步的帮助,请随时提问!
更多关于Flutter NFC读写插件ndef的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter NFC读写插件ndef的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,关于在Flutter中使用NFC读写插件进行NDEF(NFC Data Exchange Format)操作,这里是一个示例代码案例,展示如何使用flutter_nfc_reader
插件来实现这一功能。请注意,这个插件主要用于读取NFC标签,而写入功能可能需要使用其他插件或者平台通道来实现,因为Flutter本身对NFC写入的支持有限。
首先,确保在pubspec.yaml
文件中添加依赖:
dependencies:
flutter:
sdk: flutter
flutter_nfc_reader: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来,在android/app/src/main/AndroidManifest.xml
文件中添加NFC权限和特性声明:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yourapp">
<uses-permission android:name="android.permission.NFC" />
<application
...>
<uses-library android:name="android.nfc" />
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_LIST"
android:resource="@xml/nfc_tech_filter" />
</application>
</manifest>
还需要在res/xml/
目录下创建一个名为nfc_tech_filter.xml
的文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.NfcF</tech>
<tech>android.nfc.tech.NfcV</tech>
<tech>android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.MifareClassic</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
</tech-list>
</resources>
现在,在Dart代码中实现NFC读取功能:
import 'package:flutter/material.dart';
import 'package:flutter_nfc_reader/flutter_nfc_reader.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
NfcManager? _nfcManager;
@override
void initState() {
super.initState();
_nfcManager = NfcManager.instance;
_nfcManager!.startSession().then((_) {
_nfcManager!.onDiscovered!.listen((NfcTag tag) {
// 当NFC标签被发现时触发
print("NFC Tag Discovered: ${tag.id}");
// 尝试读取NDEF消息
tag.ndef?.readNdefMessages().then((ndefMessages) {
ndefMessages.forEach((message) {
print("NDEF Message: ${message.toJson()}");
});
}).catchError((error) {
print("Error reading NDEF: $error");
});
});
}).catchError((error) {
print("Error starting NFC session: $error");
});
}
@override
void dispose() {
_nfcManager?.endSession();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter NFC Reader'),
),
body: Center(
child: Text('Place your NFC tag near the device to read it.'),
),
),
);
}
}
请注意,这个示例代码只展示了如何读取NFC标签上的NDEF消息。对于写入NDEF消息,由于Flutter社区对NFC写入的直接支持有限,你可能需要使用平台通道与原生Android或iOS代码进行交互来实现这一功能。这通常涉及到编写自定义的原生插件或者利用现有的原生NFC写入库。
此外,确保在测试应用时,设备已经启用了NFC功能,并且应用具有相应的权限。