入门
-
安装软件包
Terminal window npm i @capgo/capacitor-nfcTerminal window pnpm add @capgo/capacitor-nfcTerminal window yarn add @capgo/capacitor-nfcTerminal window bun add @capgo/capacitor-nfc -
与原生项目同步
Terminal window npx cap syncTerminal window pnpm cap syncTerminal window yarn cap syncTerminal window bunx cap sync
iOS 配置
Section titled “iOS 配置”将 NFC 使用说明添加到您的 Info.plist 中:
<key>NFCReaderUsageDescription</key><string>This app needs NFC access to read and write tags</string>在 Xcode 项目中启用近场通信标签读取功能。
Android 配置
Section titled “Android 配置”将 NFC 权限添加到您的 AndroidManifest.xml:
<manifest> <uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="false" /></manifest>开始扫描 NFC 标签
Section titled “开始扫描 NFC 标签”import { CapacitorNfc } from '@capgo/capacitor-nfc';
await CapacitorNfc.startScanning({ invalidateAfterFirstRead: false, // Keep session open (iOS) alertMessage: 'Hold a tag near the top of your device.',});
const listener = await CapacitorNfc.addListener('nfcEvent', (event) => { console.log('Tag detected:', event.type); console.log('Tag ID:', event.tag?.id); console.log('NDEF message:', event.tag?.ndefMessage);});读取 NFC 标签
Section titled “读取 NFC 标签”await CapacitorNfc.addListener('nfcEvent', (event) => { if (event.tag?.ndefMessage) { event.tag.ndefMessage.forEach(record => { console.log('TNF:', record.tnf); console.log('Type:', record.type); console.log('Payload:', record.payload);
// Decode text record if (record.tnf === 1 && record.type[0] === 0x54) { // Text record const langLen = record.payload[0] & 0x3f; const text = new TextDecoder().decode( new Uint8Array(record.payload.slice(langLen + 1)) ); console.log('Text:', text); } }); }});写入 NFC 标签
Section titled “写入 NFC 标签”// Prepare a text recordconst encoder = new TextEncoder();const langBytes = Array.from(encoder.encode('en'));const textBytes = Array.from(encoder.encode('Hello NFC'));const payload = [langBytes.length & 0x3f, ...langBytes, ...textBytes];
await CapacitorNfc.write({ allowFormat: true, records: [ { tnf: 0x01, // TNF Well-known type: [0x54], // 'T' for Text id: [], payload, }, ],});
console.log('Tag written successfully');将 URL 写入 NFC 标签
Section titled “将 URL 写入 NFC 标签”const url = 'https://capgo.app';const urlBytes = Array.from(new TextEncoder().encode(url));
await CapacitorNfc.write({ allowFormat: true, records: [ { tnf: 0x01, // TNF Well-known type: [0x55], // 'U' for URI id: [], payload: [0x01, ...urlBytes], // 0x01 = https:// }, ],});擦除 NFC 标签
Section titled “擦除 NFC 标签”await CapacitorNfc.erase();console.log('Tag erased');将标签设置为只读
Section titled “将标签设置为只读”await CapacitorNfc.makeReadOnly();console.log('Tag is now read-only');await listener.remove();await CapacitorNfc.stopScanning();检查 NFC 状态
Section titled “检查 NFC 状态”const { status } = await CapacitorNfc.getStatus();console.log('NFC status:', status);// Possible values: 'NFC_OK', 'NO_NFC', 'NFC_DISABLED', 'NDEF_PUSH_DISABLED'
if (status === 'NFC_DISABLED') { // Open system settings await CapacitorNfc.showSettings();}Android 光束(P2P 共享)
Section titled “Android 光束(P2P 共享)”// Share data via Android Beamconst message = { records: [ { tnf: 0x01, type: [0x54], // Text id: [], payload: [/* text record payload */], }, ],};
await CapacitorNfc.share(message);
// Later, stop sharingawait CapacitorNfc.unshare();API 参考
Section titled “API 参考”开始扫描(选项?)
Section titled “开始扫描(选项?)”开始监听 NFC 标签。
interface StartScanningOptions { invalidateAfterFirstRead?: boolean; // iOS only, defaults to true alertMessage?: string; // iOS only androidReaderModeFlags?: number; // Android only}
await CapacitorNfc.startScanning(options);停止扫描()
Section titled “停止扫描()”停止 NFC 扫描会话。
await CapacitorNfc.stopScanning();将 NDEF 记录写入最后发现的标签。
interface WriteTagOptions { records: NdefRecord[]; allowFormat?: boolean; // Defaults to true}
interface NdefRecord { tnf: number; // Type Name Format type: number[]; // Record type id: number[]; // Record ID payload: number[]; // Record payload}
await CapacitorNfc.write(options);删除最后发现的标签。
await CapacitorNfc.erase();makeReadOnly()
Section titled “makeReadOnly()”将最后发现的标签设置为只读(永久)。
await CapacitorNfc.makeReadOnly();分享(选项)
Section titled “分享(选项)”通过 Android Beam 共享 NDEF 消息(仅限 Android)。
await CapacitorNfc.share({ records: [...] });取消共享()
Section titled “取消共享()”停止共享(仅限 Android)。
await CapacitorNfc.unshare();获取状态()
Section titled “获取状态()”获取当前 NFC 适配器状态。
const { status } = await CapacitorNfc.getStatus();// Returns: 'NFC_OK' | 'NO_NFC' | 'NFC_DISABLED' | 'NDEF_PUSH_DISABLED'显示设置()
Section titled “显示设置()”打开系统 NFC 设置。
await CapacitorNfc.showSettings();发现 NFC 标签时触发。
interface NfcEvent { type: 'tag' | 'ndef' | 'ndef-mime' | 'ndef-formattable'; tag?: NfcTag;}
interface NfcTag { id: number[]; techTypes: string[]; type: string | null; maxSize: number | null; isWritable: boolean | null; canMakeReadOnly: boolean | null; ndefMessage: NdefRecord[] | null;}nfcStateChange
Section titled “nfcStateChange”当 NFC 适配器可用性发生变化时触发(仅限 Android)。
interface NfcStateChangeEvent { status: NfcStatus; enabled: boolean;}import { CapacitorNfc } from '@capgo/capacitor-nfc';
export class NfcService { private listener: any;
async startReading() { // Check NFC status const { status } = await CapacitorNfc.getStatus();
if (status === 'NO_NFC') { throw new Error('NFC not available on this device'); }
if (status === 'NFC_DISABLED') { await CapacitorNfc.showSettings(); return; }
// Start scanning await CapacitorNfc.startScanning({ invalidateAfterFirstRead: false, alertMessage: 'Ready to scan NFC tags', });
// Listen for tags this.listener = await CapacitorNfc.addListener('nfcEvent', (event) => { this.handleNfcEvent(event); }); }
private handleNfcEvent(event: any) { console.log('NFC Event:', event.type);
if (event.tag?.ndefMessage) { event.tag.ndefMessage.forEach(record => { this.processRecord(record); }); } }
private processRecord(record: any) { // Process text records if (record.tnf === 1 && record.type[0] === 0x54) { const langLen = record.payload[0] & 0x3f; const text = new TextDecoder().decode( new Uint8Array(record.payload.slice(langLen + 1)) ); console.log('Text:', text); }
// Process URI records if (record.tnf === 1 && record.type[0] === 0x55) { const uriCode = record.payload[0]; const uri = new TextDecoder().decode( new Uint8Array(record.payload.slice(1)) ); console.log('URI:', uri); } }
async writeText(text: string) { const encoder = new TextEncoder(); const langBytes = Array.from(encoder.encode('en')); const textBytes = Array.from(encoder.encode(text)); const payload = [langBytes.length & 0x3f, ...langBytes, ...textBytes];
await CapacitorNfc.write({ allowFormat: true, records: [ { tnf: 0x01, type: [0x54], id: [], payload, }, ], }); }
async stopReading() { if (this.listener) { await this.listener.remove(); } await CapacitorNfc.stopScanning(); }}NDEF 记录类型
Section titled “NDEF 记录类型”TNF(类型名称格式)
Section titled “TNF(类型名称格式)”0x00:空0x01:众所周知(例如文本、URI)0x02:MIME 媒体类型0x03:绝对 URI0x04:外部类型0x05:未知0x06:不变0x07:保留
常见记录类型
Section titled “常见记录类型”- 文本:
type: [0x54](‘T’) - URI:
type: [0x55](‘U’) - 智能海报:
type: [0x53, 0x70](‘Sp’)
URI 前缀
Section titled “URI 前缀”0x00:(无前缀)0x01:https://0x02:https://0x03:http://0x04:https://www.
- 检查 NFC 状态:始终验证 NFC 是否可用并已启用
- 处理权限:适当请求 NFC 权限
- 停止扫描:完成后始终停止扫描以节省电池
- 错误处理:将 NFC 操作包装在 try-catch 块中
- 在设备上测试:NFC 功能在模拟器/仿真器上不起作用
- 需要 iOS 11.0+
- 使用核心 NFC 框架
- 支持后台标签读取(iOS 13+)
- 仅限读取 NDEF 格式的标签
- 无法在后台写入标签
- 需要 Info.plist 中的 NFCReaderUsageDescription### Android
- 需要 Android 4.4 (API 19)+
- 使用 Android NFC API
- 支持前台和后台标签读取
- 可以写入标签
- 在具有 NFC 的设备上支持 Android Beam (P2P)
- 需要 AndroidManifest.xml 中的 NFC 权限
- 不支持网络平台