更新记录

1.0.0(2026-01-31) 下载此版本

本项目采用nativejs (plus.androidd)封装android nfc 操作逻辑, 包含完整的读/写/状态监听等业务逻辑, 稳定可靠,无需额外定制修改,直接集成即可. 本插件为普通的vuehook (vueUse) 代码, 引入后直接import 即可使用. 本插件无需自定义底座, 直接在线真机调试,快速开发nfc相关功能. 示例:

<script setup>
import useNFC from '@/src/nfc/useNFC.js';
const nfc = useNFC(false); // false 表示非只读模式
const tagData = ref(null);
const { isNfcEnabled, openNfcSetting, readNfc, writetNfc, stopReadNfc } = nfc;

平台兼容性

uni-app(3.91)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
× × × 4.4 × ×
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
× × × × × × × × × × × ×

其他

多语言 暗黑模式 宽屏模式

useNFC 使用说明文档

概述

useNFC 是一个用于在 uni-app 应用中进行 NFC 标签读写的 Vue 3 组合式函数(Composable)。该函数封装了 Android 平台的 NFC 功能,提供了简便的 API 来读取和写入 NDEF 格式的 NFC 标签。

导出的常量

RTDs (Record Type Definitions)

NDEF 记录类型定义,用于标识不同类型的 NDEF 记录。

export const RTDs = {
  RTD_TEXT: "T",                          // 文本类型
  RTD_URI: "U",                           // URI 类型
  RTD_SMART_POSTER: "Sp",                 // 智能海报
  RTD_ALTERNATIVE_CARRIER: "ac",          // 备选载体
  RTD_HANDOVER_CARRIER: "Hc",             // 交接载体
  RTD_HANDOVER_REQUEST: "Hr",             // 交接请求
  RTD_HANDOVER_SELECT: "Hs",              // 交接选择
  RTD_ANDROID_APP: "android.com:pkg",     // Android 应用
}

TNFs (Type Name Format)

TNF 类型枚举,用于定义 NDEF 记录的类型名称格式。

export const TNFs = {
  TNF_EMPTY: 0x00,           // 空
  TNF_WELL_KNOWN: 0x01,      // 已知类型
  TNF_MIME_MEDIA: 0x02,      // MIME 媒体类型
  TNF_ABSOLUTE_URI: 0x03,    // 绝对 URI
  TNF_EXTERNAL_TYPE: 0x04,   // 外部类型
  TNF_UNKNOWN: 0x05,         // 未知类型
  TNF_UNCHANGED: 0x06,       // 未改变
  TNF_RESERVED: 0x07,        // 保留
}

主函数

useNFC(readonly, techList)

创建 NFC 实例的主函数。

参数

参数名 类型 默认值 说明
readonly Boolean - 是否只读模式。只读模式下,写操作不生效
techList String[][] DEFAULT_TECH_LIST 可操作的标签技术类型列表

默认支持的标签类型

const DEFAULT_TECH_LIST = [
  ['android.nfc.tech.IsoDep'],
  ['android.nfc.tech.NfcA'],
  ['android.nfc.tech.NfcB'],
  ['android.nfc.tech.NfcF'],
  ['android.nfc.tech.Nfcf'],
  ['android.nfc.tech.NfcV'],
  ['android.nfc.tech.NdefFormatable'],
  ['android.nfc.tech.MifareClassi'],
  ['android.nfc.tech.MifareUltralight']
]

返回值

返回一个包含以下属性和方法的对象:

返回对象属性和方法

1. isNfcEnabled

  • 类型: Ref<Boolean>
  • 说明: 响应式状态,表示设备 NFC 功能是否已开启
  • 示例:
    const { isNfcEnabled } = useNFC(false);
    console.log(isNfcEnabled.value); // true 或 false

2. isNfcRunning

  • 类型: Ref<Boolean>
  • 说明: 响应式状态,表示当前是否正在监听 NFC 标签
  • 示例:
    const { isNfcRunning } = useNFC(false);
    console.log(isNfcRunning.value); // true 或 false

3. openNfcSetting()

打开系统的 NFC 设置界面。

参数

返回值

示例

const { openNfcSetting } = useNFC(false);
openNfcSetting(); // 打开 NFC 设置页面

4. readNfc(callback)

读取 NFC 标签内容。当检测到标签时,会自动读取并回调。

参数

参数名 类型 说明
callback Function 读取成功后的回调函数

callback 参数

回调函数接收一个参数 tagData,格式如下:

// tagData 是一个数组,每个元素代表一个 NDEF 记录
[
  {
    tnf: Number,        // TNF 类型码(对应 TNFs 常量)
    type: String,       // 记录类型(对应 RTDs 常量)
    payload: Any        // 记录负载内容(根据类型可能是字符串、Uint8Array 等)
  },
  // ... 更多记录
]

返回值

示例

const { readNfc } = useNFC(false);

readNfc((tagData) => {
  if (!tagData) {
    console.log('标签为空或读取失败');
    return;
  }

  tagData.forEach((record, index) => {
    console.log(`记录 ${index + 1}:`);
    console.log(`  TNF: ${record.tnf}`);
    console.log(`  Type: ${record.type}`);
    console.log(`  Payload:`, record.payload);
  });
});

5. stopReadNfc()

停止 NFC 监听。通常在组件卸载时会自动调用,但也可以手动调用提前停止监听。

参数

返回值

示例

const { stopReadNfc } = useNFC(false);
stopReadNfc(); // 停止监听

6. writeNfc(records, callback)

向 NFC 标签写入数据。

参数

参数名 类型 说明
records NdefRecord \| NdefRecord[] 要写入的 NDEF 记录,可以是单个记录或记录数组。通过 creator 对象创建
callback Function 写入完成后的回调函数

callback 参数

回调函数接收一个 error 参数:

  • 如果写入成功,errornull
  • 如果写入失败,error 为错误信息字符串

返回值

示例

const { writeNfc, creator } = useNFC(false);

// 创建文本记录
const textRecord = creator.createTextRecord('Hello NFC');

// 写入单个记录
writeNfc(textRecord, (error) => {
  if (error) {
    console.error('写入失败:', error);
  } else {
    console.log('写入成功!');
  }
});

// 或写入多个记录
const uriRecord = creator.createUri('https://example.com');
writeNfc([textRecord, uriRecord], (error) => {
  if (error) {
    console.error('写入失败:', error);
  } else {
    console.log('写入成功!');
  }
});

7. creator

用于创建 NDEF 记录的辅助对象,包含以下方法:

creator.createApplicationRecord(packageName)

创建 Android 应用记录。

参数
参数名 类型 说明
packageName String Android 应用包名(如 "com.example.app")
返回值

NdefRecord 对象

示例
const { creator } = useNFC(false);
const record = creator.createApplicationRecord('com.example.app');

creator.createUri(uriStr)

创建 URI 记录。

参数
参数名 类型 说明
uriStr String URI 字符串(如 "https://example.com")
返回值

NdefRecord 对象

示例
const { creator } = useNFC(false);
const record = creator.createUri('https://example.com');

creator.createMime(mimeType, dataBytes)

创建 MIME 类型记录。

参数
参数名 类型 说明
mimeType String MIME 类型(如 "text/plain", "application/json")
dataBytes Number[] \| Uint8Array 数据字节数组
返回值

NdefRecord 对象

示例
const { creator } = useNFC(false);
const text = 'Hello World';
const dataBytes = Array.from(new TextEncoder().encode(text));
const record = creator.createMime('text/plain', dataBytes);

creator.createTextRecord(text)

创建文本记录。

参数
参数名 类型 说明
text String 要写入的文本内容
返回值

NdefRecord 对象

示例
const { creator } = useNFC(false);
const record = creator.createTextRecord('Hello NFC');

8. onNfcEvent(callback)

监听 NFC 操作事件,用于在操作的不同阶段做出响应(如显示提示)。

参数

参数名 类型 说明
callback Function 事件回调函数,如果传入 null 或不传,则使用默认回调

callback 参数

回调函数接收两个参数:

  • event: 事件类型字符串
  • msg: 消息对象(当前未使用,保留用于扩展)

事件类型

事件名 触发时机
"read_start" 开始读取标签时
"write_start" 开始写入标签时
"complete" 操作完成时
"error" 操作出错时

返回值

示例

const { onNfcEvent } = useNFC(false);

// 自定义事件处理
onNfcEvent((event, msg) => {
  switch (event) {
    case 'read_start':
      console.log('开始读取,请将卡片贴近手机');
      break;
    case 'write_start':
      console.log('开始写入,请将卡片贴近手机');
      break;
    case 'complete':
      console.log('操作完成!');
      break;
    case 'error':
      console.log('操作失败,请重试');
      break;
  }
});

// 恢复默认事件处理
onNfcEvent(null); // 或不传参数

使用示例

完整示例:读取 NFC 标签

<template>
  <view>
    <view v-if="!isNfcEnabled">NFC 未开启,请先开启 NFC 功能</view>
    <button @click="openNfcSetting">打开 NFC 设置</button>
    <button @click="startRead">开始读取</button>
    <button @click="stopRead">停止读取</button>
    <view v-if="tagData">
      <text>读取到的数据:</text>
      <view v-for="(record, index) in tagData" :key="index">
        <text>记录 {{ index + 1 }}:</text>
        <text>类型: {{ record.type }}</text>
        <text>内容: {{ record.payload }}</text>
      </view>
    </view>
  </view>
</template>

<script setup>
import { ref } from 'vue';
import useNFC from '@/src/nfc/useNFC.js';

const nfc = useNFC(false); // false 表示非只读模式
const tagData = ref(null);

const { isNfcEnabled, openNfcSetting, readNfc, stopReadNfc } = nfc;

const startRead = () => {
  readNfc((data) => {
    tagData.value = data;
    console.log('读取到数据:', data);
  });
};

const stopRead = () => {
  stopReadNfc();
  console.log('已停止读取');
};
</script>

完整示例:写入 NFC 标签

<template>
  <view>
    <view v-if="!isNfcEnabled">NFC 未开启</view>
    <button @click="writeText">写入文本</button>
    <button @click="writeUri">写入 URI</button>
  </view>
</template>

<script setup>
import useNFC from '@/src/nfc/useNFC.js';

const nfc = useNFC(false); // false 表示非只读模式
const { writeNfc, creator } = nfc;

const writeText = () => {
  const record = creator.createTextRecord('Hello NFC!');
  writeNfc(record, (error) => {
    if (error) {
      console.error('写入失败:', error);
    } else {
      console.log('文本写入成功!');
    }
  });
};

const writeUri = () => {
  const record = creator.createUri('https://example.com');
  writeNfc(record, (error) => {
    if (error) {
      console.error('写入失败:', error);
    } else {
      console.log('URI 写入成功!');
    }
  });
};
</script>

只读模式示例

// 创建只读模式的 NFC 实例
const nfc = useNFC(true); // true 表示只读模式

// 尝试写入会失败
const { writeNfc, creator } = nfc;
const record = creator.createTextRecord('Test');
writeNfc(record, (error) => {
  // error: "只读模式下,写操作不生效"
  console.error(error);
});

平台兼容性

  • Android: 完全支持(通过 #ifdef APP-PLUS 条件编译)
  • iOS: 当前未实现
  • H5/小程序: 不支持,调用相关方法会显示"系统不支持"提示

注意事项

  1. 权限要求: 应用需要声明 NFC 权限
  2. 设备要求: 设备必须具备 NFC 硬件功能
  3. 生命周期管理: 组件卸载时会自动停止监听,但也可以手动调用 stopReadNfc() 提前停止
  4. 写入一次性: writeNfc 的回调函数是一次性的,成功写入一次后会被自动清除
  5. 卡片位置: 提示用户将卡片贴近手机顶部摄像头位置
  6. 只读模式: 在只读模式下,所有写操作都会被阻止
  7. 异步操作: 读取和写入都是异步操作,需要等待卡片贴近

常见问题

1. NFC 未开启

使用 isNfcEnabled 检查 NFC 状态,如未开启可调用 openNfcSetting() 引导用户开启。

2. 读取失败

  • 确认标签格式为 NDEF
  • 确认标签类型在 techList
  • 确认卡片正确贴近手机 NFC 感应区域

3. 写入失败

  • 确认非只读模式
  • 确认标签支持写入
  • 确认标签未锁定为只读

4. 多次读取问题

每次调用 readNfc() 都会覆盖之前的回调函数,不会重复回调。如需重新读取,请再次调用 readNfc()

隐私、权限声明

1. 本插件需要申请的系统权限列表:

<!-- NFC Permission --> <uses-permission android:name="android.permission.NFC" /> <!-- NFC Feature Requirement --> <uses-feature android:name="android.hardware.nfc" android:required="true" />

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。