跳转到内容

入门

  1. 安装软件包

    Terminal window
    npm i @capgo/capacitor-nfc
  2. 与原生项目同步

    Terminal window
    npx cap sync

将 NFC 使用说明添加到您的 Info.plist 中:

<key>NFCReaderUsageDescription</key>
<string>This app needs NFC access to read and write tags</string>

在 Xcode 项目中启用近场通信标签读取功能。

将 NFC 权限添加到您的 AndroidManifest.xml

<manifest>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
</manifest>
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);
});
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);
}
});
}
});
// Prepare a text record
const 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');
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://
},
],
});
await CapacitorNfc.erase();
console.log('Tag erased');
await CapacitorNfc.makeReadOnly();
console.log('Tag is now read-only');
await listener.remove();
await CapacitorNfc.stopScanning();
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();
}
// Share data via Android Beam
const message = {
records: [
{
tnf: 0x01,
type: [0x54], // Text
id: [],
payload: [/* text record payload */],
},
],
};
await CapacitorNfc.share(message);
// Later, stop sharing
await CapacitorNfc.unshare();

开始监听 NFC 标签。

interface StartScanningOptions {
invalidateAfterFirstRead?: boolean; // iOS only, defaults to true
alertMessage?: string; // iOS only
androidReaderModeFlags?: number; // Android only
}
await CapacitorNfc.startScanning(options);

停止 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();

将最后发现的标签设置为只读(永久)。

await CapacitorNfc.makeReadOnly();

通过 Android Beam 共享 NDEF 消息(仅限 Android)。

await CapacitorNfc.share({ records: [...] });

停止共享(仅限 Android)。

await CapacitorNfc.unshare();

获取当前 NFC 适配器状态。

const { status } = await CapacitorNfc.getStatus();
// Returns: 'NFC_OK' | 'NO_NFC' | 'NFC_DISABLED' | 'NDEF_PUSH_DISABLED'

打开系统 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;
}

当 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();
}
}
  • 0x00:空
  • 0x01:众所周知(例如文本、URI)
  • 0x02:MIME 媒体类型
  • 0x03:绝对 URI
  • 0x04:外部类型
  • 0x05:未知
  • 0x06:不变
  • 0x07:保留
  • 文本type: [0x54] (‘T’)
  • URItype: [0x55](‘U’)
  • 智能海报type: [0x53, 0x70](‘Sp’)
  • 0x00:(无前缀)
  • 0x01https://
  • 0x02https://
  • 0x03http://
  • 0x04: https://www.
  1. 检查 NFC 状态:始终验证 NFC 是否可用并已启用
  2. 处理权限:适当请求 NFC 权限
  3. 停止扫描:完成后始终停止扫描以节省电池
  4. 错误处理:将 NFC 操作包装在 try-catch 块中
  5. 在设备上测试: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 权限
  • 不支持网络平台