更新记录
1.3.0(2026-04-29)
一、iOS异常日志收紧
1.2.9(2026-04-29)
一、iOS相关
1.2.8(2026-04-28)
一、iOS 标签写入相关问题
查看更多平台兼容性
uni-app(4.66)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-nvue | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.3.0 | √ | 1.3.0 | - | - | - | × | 4.4 | 1.3.0 | 16 | 1.3.0 | 12 | 1.3.0 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| - | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.66)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
UTS环境兼容性
| uni-app | uni-app x |
|---|---|
| √ | √ |
hl-nfccase-uts
跨端 NFC 读/写 插件(Android / iOS / HarmonyOS)。
阅读指引(按角色)
| 你想… | 直接看 |
|---|---|
| 5 分钟跑通读卡 | 快速开始 → 平台差异 |
| 查有哪些方法 | API 参考 |
| 写 NDEF / 写块 / transceive | 按场景示例 |
| 事件里有哪些字段 | 返回数据结构 |
Android 自定义基座、后台碰卡、报错 reason |
注意事项 里 Android 小节 |
快速开始
- 安装插件后,Android 需自定义基座或重新打包(插件含 NFC Manifest / 后台分发 Activity)。
- 页面里调用
configure(可选,调去重/队列等),再onTagDiscovered注册回调。 - 仅 iOS / HarmonyOS:用户要点按钮或你主动调用
startNFCSession();Android 前台自动监听,一般不用startNFCSession。
最小示例(推荐:<script setup>)
import { onTagDiscovered, startNFCSession, stopNFCSession, configure } from '@/uni_modules/hl-nfccase-uts'
import { onShow, onHide } from '@dcloudio/uni-app'
onShow(() => {
configure({ pendingMax: 10, dedupeMs: 600 })
onTagDiscovered((event) => {
console.log('UID:', event.uidHex, event)
})
// #ifdef APP-IOS || APP-HARMONY
startNFCSession()
// #endif
})
onHide(() => {
// #ifdef APP-IOS || APP-HARMONY
stopNFCSession()
// #endif
})
判断能力:isNfcSupported() / isNfcEnabled()。
uni-app(Options API,完整可复制)
与 <script setup> 逻辑相同:页面显示时 configure;点击「开始扫描」注册 onTagDiscovered 并在 iOS/Harmony 启动会话;页面隐藏时停止会话。
<template>
<view class="container">
<button @click="startScan">开始扫描 NFC</button>
<button @click="stopScan">停止扫描</button>
<view v-if="tagData">
<text>UID: {{ tagData.uidHex }}</text>
</view>
</view>
</template>
<script>
import {
onTagDiscovered,
startNFCSession,
stopNFCSession,
configure
} from '@/uni_modules/hl-nfccase-uts'
export default {
data() {
return {
tagData: null
}
},
onShow() {
configure({ pendingMax: 10, dedupeMs: 600 })
},
onHide() {
this.stopScan()
},
methods: {
startScan() {
// 注册回调
onTagDiscovered((event) => {
console.log('NFC 标签:', event)
this.tagData = event
})
// #ifdef APP-IOS || APP-HARMONY
startNFCSession()
// #endif
},
stopScan() {
// #ifdef APP-IOS || APP-HARMONY
stopNFCSession()
// #endif
}
}
}
</script>
平台差异一览
一句话
- Android:前台自动收卡;高级读写依赖内存里的
Tag,注意activeTagTtlMs;可refreshActiveTagSync()写后重读。 - iOS:必须
startNFCSession(),有系统弹窗;NDEF 写入需开启keepSessionAlive并在同一会话内完成,不支持 Mifare 直读块、NfcA/B raw transceive。 - HarmonyOS:需
startNFCSession();读写能力与 Android 接近,见下表。
能力对比表
| 特性 | Android | iOS | HarmonyOS |
|---|---|---|---|
| 启动方式 | 自动监听 | 需 startNFCSession() |
需 startNFCSession() |
| 系统弹窗 | 无 | 有 | 无 |
| FeliCa | ✅ | ❌ | ✅ |
| Mifare Classic 读块 | ✅ | ❌ | ✅ |
| NDEF 写入 | ✅ | ✅(需 keepSessionAlive) | ✅ |
| Mifare 写块/写页 | ✅ | ❌ | ✅ |
| NdefFormatable 格式化 | ✅ | ❌ | ❌ |
| NfcA/NfcB Raw Transceive | ✅ | ❌ | ❌ |
| 最低系统 | Android 5.0+ | iOS 13.0+ | HarmonyOS 3.0+ |
默认回调里会尽量解析 UID、技术列表、NDEF 文本/URI;不会默认读 Mifare 扇区内容(需密钥,易因卡而异)。
支持的技术类型(摘要)
| 平台 | 常见支持 |
|---|---|
| Android | NDEF、Mifare Classic/Ultralight、IsoDep、NfcA/B/F/V |
| iOS | ISO14443(MiFare、ISO7816)、ISO15693(NFC-V);无 FeliCa |
| HarmonyOS | 与 Android 类似,见各 techs 字段 |
API 参考
基础能力
| 方法 | 平台 | 说明 |
|---|---|---|
onTagDiscovered(callback) |
全平台 | 注册碰卡回调 |
startNFCSession() / stopNFCSession() |
iOS/HarmonyOS | 启停前台扫描 |
getPendingTagSync(clearRead) |
全平台 | 读一条缓存(后台/冷启动) |
getPendingTagsSync(clearRead, max) |
全平台 | 读多条缓存 |
refreshActiveTagSync() |
三端 | 写后不离卡,重读当前标签快照 |
clearPendingTag() |
全平台 | 只清 磁盘缓存队列 |
clearActiveTag() |
全平台 | 清 内存活动标签 + 去重状态 |
resetNfcState() |
全平台 | 上两者都做 |
isNfcSupported() / isNfcEnabled() |
全平台 | 能力与开关 |
configure(options) |
全平台 | 见下表 |
clearReadCache() |
全平台 | Android 侧多为占位,保留接口一致 |
checkAndSaveCurrentIntentNfc() |
Android | 兜底:从当前 Activity Intent 取 NFC |
checkNfcDispatchCalled() |
Android | 调试:分发 Activity 是否被调过 |
configure 常用字段(Android):useReaderMode、activeTagTtlMs(默认可操作时间窗,默认 5000)、dedupeMs(同 UID 去重窗口)、pendingMax、skipNdefCheck。iOS 另有 keepSessionAlive 等,见下方注意事项。
读 / 写 API
| 方法 | 平台 |
|---|---|
mifareClassicReadSector / ReadBlock / WriteBlock |
Android/HarmonyOS |
mifareUltralightReadPages / WritePage |
Android/HarmonyOS |
isoDepTransceive / nfcVTransceive |
Android/HarmonyOS |
nfcATransceive / nfcBTransceive |
仅 Android |
ndefWrite / ndefFormatAndWrite |
ndefWrite 支持 Android/iOS/HarmonyOS(iOS 需 keepSessionAlive);ndefFormatAndWrite 仅 Android |
按场景示例
读卡 + 判断 NFC
import { onTagDiscovered, isNfcSupported, isNfcEnabled } from '@/uni_modules/hl-nfccase-uts'
if (!isNfcSupported() || !isNfcEnabled()) { /* 提示用户 */ }
onTagDiscovered((e) => { console.log(e.uidHex, e.ndefText, e.ndefUri) })
// Android 无需 startNFCSession;iOS/Harmony 需先 startNFCSession,见快速开始
写入 NDEF(Android / iOS / HarmonyOS)
import { ndefWrite, onTagDiscovered } from '@/uni_modules/hl-nfccase-uts'
// iOS 写入前需要 configure({ keepSessionAlive: true, activeTagTtlMs: 10000 })
onTagDiscovered(() => {
const res = ndefWrite([
{ type: 'text', data: 'Hello', lang: 'en' },
{ type: 'uri', data: 'https://example.com' }
])
if (res.code !== 0) console.error(res.data.error)
})
写后立刻重读(推荐 Android 调大 activeTagTtlMs)
import { ndefWrite, refreshActiveTagSync, configure } from '@/uni_modules/hl-nfccase-uts'
configure({ activeTagTtlMs: 10000 })
const w = ndefWrite([{ type: 'text', data: 'Hi', lang: 'en' }])
if (w.code === 0) {
const r = refreshActiveTagSync()
if (r.code === 0) console.log(r.data.ndefText)
}
格式化空白卡(仅 Android)
import { ndefFormatAndWrite, onTagDiscovered } from '@/uni_modules/hl-nfccase-uts'
onTagDiscovered(() => {
const res = ndefFormatAndWrite([{ type: 'text', data: 'Hello', lang: 'en' }])
// 仅格式化:ndefFormatAndWrite([])
})
Mifare 写块 / Ultralight 写页
在 onTagDiscovered 同一贴卡时间窗内调用(默认约 5s,可 configure({ activeTagTtlMs }))。
mifareClassicWriteBlock(4, 'A', 'FFFFFFFFFFFF', '00112233445566778899AABBCCDDEEFF')
mifareUltralightWritePage(4, '00112233')
NfcA / NfcB raw(仅 Android)
nfcATransceive('3004') // Type2 读示例,具体命令依芯片文档
nfcBTransceive('05...')
勿随意写 Ultralight 低页;有 NDEF 时优先 ndefWrite。
清理状态(缓存 vs 内存标签)
import { clearPendingTag, clearActiveTag, resetNfcState } from '@/uni_modules/hl-nfccase-uts'
clearPendingTag() // 只清队列
clearActiveTag() // 只清内存 Tag + 去重
resetNfcState() // 两者都清
| 方法 | 缓存队列 | 活动标签 | 去重 |
|---|---|---|---|
clearPendingTag |
✅ | ❌ | ❌ |
clearActiveTag |
❌ | ✅ | ✅ |
resetNfcState |
✅ | ✅ | ✅ |
返回数据结构
字段因平台略有不同,常见:timestamp、action、uidHex、techs、ndef / ndefText / ndefUri、extras。
Android(示例)
{
"timestamp": 1769741815417,
"action": "TECH_DISCOVERED",
"uidHex": "04A1B2C3D4E5F6",
"techs": ["android.nfc.tech.NfcA", "android.nfc.tech.Ndef"],
"ndefText": "文本内容",
"ndefUri": "https://example.com",
"extras": { /* nfcA / mifareClassic 等 */ }
}
iOS(示例)
{
"timestamp": 1769741815417,
"action": "iOS_CoreNFC_MiFare",
"uidHex": "53318EF7210001",
"techs": ["MiFare", "MiFareUnknown"],
"ndefUri": "https://example.com"
}
HarmonyOS(示例)
{
"timestamp": 1769741815417,
"action": "Harmony_NFC_TAG",
"uidHex": "04A1B2C3D4E5F6",
"techs": ["NfcA", "MifareClassic", "Ndef"],
"ndefText": "文本内容",
"extras": { }
}
注意事项
所有平台
- 高级读写失败统一
{ code: -1, data: { error, reason? } },请以res.data.error为准。 getPendingTagSync/onTagDiscovered:偏「事件」;refreshActiveTagSync:偏「当前卡写后重读」。
Android(必读)
- 自定义基座或重打包(含 NFC Intent、后台
NfcDispatchActivity)。 - 后台/冷启动碰卡会先缓存,前端在
onShow等时机用getPendingTagSync(true)消费并自行跳转。 - 同一张卡在不同机型上
techs可能不同;仅有NfcA而无MifareUltralight时,用nfcATransceive或ndefWrite,不要强行mifareUltralightReadPages。 - *`mifareUltralight
** 要求 techList 里真有android.nfc.tech.MifareUltralight`。
Android(进阶 / 排错)
- 活动标签:高级 API 依赖进程内最近一次扫描的
Tag;仅读过磁盘缓存不算「有 Tag」。超时见TAG_TTL_EXPIRED,可调大activeTagTtlMs或重新贴卡。 reason字段:NO_TAG_IN_MEMORY(内存无 Tag)、TAG_TTL_EXPIRED(附带elapsedMs/ttlMs);其它如卡移开见error原文。- 插件已处理 Intent 消费防重复、ReaderMode 去重、读写后延长去重,一般无需自己管;若仍异常,可
resetNfcState()再试。
iOS
- Info.plist
NFCReaderUsageDescription、Xcode NFC Capability、Entitlements 含 NDEF + TAG。 - 无后台唤醒;每次扫描通常需
startNFCSession()。 - 每次新会话会丢弃上一轮未送达的旧回调;可选
clearPendingTag()再注册回调。 - 会话内续读可
configure({ keepSessionAlive: true, activeTagTtlMs: 10000 })+refreshActiveTagSync()。
HarmonyOS
ohos.permission.NFC_TAG;需startNFCSession()。
常见问题(精简)
Q:为什么有 UID 但 ndefWrite 报没有活动标签?
A:可能只有缓存、没有本次前台扫描到的 Tag。请重新贴卡或先 onTagDiscovered 再写,并检查 activeTagTtlMs。
Q:Android 为什么写一次又触发一次回调?
A:射频断开再连会再发现同卡;插件已做去重与写后延长去重,仍异常可试 dedupeMs 或 resetNfcState()。
Q:iOS 能写 NDEF 吗?
A:可以写 NDEF,但必须先 configure({ keepSessionAlive: true }),再 startNFCSession(),并在 onTagDiscovered 回调里马上调用 ndefWrite()。离开会话或插件读完后自动关闭会话,都会导致写入失败。
文档版本随插件迭代;完整方法签名以 utssdk/interface.uts 为准。

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 276
赞赏 2
下载 11763454
赞赏 1911
赞赏
京公网安备:11010802035340号