更新记录
1.2.8(2026-09-07)
- 修复 Android:success/fail 回调 ClassCast(扁平 Option 不可强转为 BaseOption;入口去掉 coerce 重建)
- .vue 直接传对象;.uvue 须
as XxxOption;须重打自定义基座并云端传统打包 - 不传参行为与上一版兼容
1.2.7(2026-09-07)
- 优化 uni-app x:入口将对象字面量归一化为 Option,业务页可直接传对象调用 API,无需再写
as XxxOption - 使用须制作自定义基座,并走云端传统打包(不支持离线打包、安心打包)
- 不传参行为与上一版兼容
1.2.6(2026-09-06)
- 修复 App 端成功回调与驱动稳定性:去掉 undefined、可变属性强制解包改为局部拷贝;iOS BLE 状态/特性用 Number.from
- 修复 Android 运行时 ClassCastException:成功回调与 onTagDiscovered 结果改为 UTSJSONObject 别名,避免强转为独立 Result 类型
- 修复标签发现回调字段读写:uid/techList 用会话局部变量,避免 UTSJSONObject 动态属性依赖
- 修复 invoke 回调判空调用;可选 number 去掉 undefined 联合;部分 Android 原生返回值改 Number.from、可变属性局部拷贝
- 使用须制作自定义基座,并走云端传统打包(不支持离线打包、安心打包)
- 【务必使用此版本及以上版本打包使用,低版本存在缺陷】
平台兼容性
uni-app(4.11)
| Vue2 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| × | √ | 1.2.6 | × | × | √ | 1.2.6 | √ | 1.2.6 | 5.0 | 1.2.6 | 12 | 1.2.6 | 12 | 1.2.6 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(4.11)
| Chrome | Safari | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 | 微信小程序 |
|---|---|---|---|---|---|---|---|---|
| × | × | 5.0 | 1.2.6 | 12 | 1.2.6 | 12 | 1.2.6 | × |
breao-nfcndef 使用说明
轻量 NFC NDEF 读写插件,适用于门禁、资产标签、点检等贴靠读写场景。
当前版本:1.2.8
- Android / iOS / 鸿蒙(含 uni-app x 鸿蒙):能力检测、前台会话、UID、Text / URI / MIME / Smart Poster / Empty 读写辅助
- Android / 鸿蒙:空白标签格式化写入、Ultralight / NTAG 页读(iOS 见能力矩阵)
- 不做微信小程序、不做 HCE 卡模拟、不做完整 ISO-DEP 透传工具
建议调用顺序:getNfcCapabilities / getNfcStatus → startNfcSession → 贴靠标签 → getNdefStatus(写入前可选)→ readNdef / writeNdef → stopNfcSession。各异步方法均支持 success / fail / complete;fail 含 errCode / errMsg。
1. 环境要求
- HBuilderX 4.11 及以上
- uni-app Vue3(App-vue / App-nvue)或 uni-app x(App-Android / App-iOS / App-鸿蒙)
- 支持:App-Android、App-iOS、App-鸿蒙(uni-app 与 uni-app x)
- 不支持:H5、微信及其它小程序
- Android 最低 API:21;iOS 最低 12;鸿蒙最低 API:12
- App 真机调试须制作自定义基座;正式发版须购买授权后走云端传统打包
- 授权绑定唯一 appid + 包名
- 真机须具备 NFC 硬件并开启系统 NFC
2. 安装与引入
将插件目录放入工程的 uni_modules/breao-nfcndef,或从插件市场导入后同步。
import {
getNfcCapabilities,
getNfcStatus,
startNfcSession,
stopNfcSession,
onTagDiscovered,
offTagDiscovered,
readNdef,
buildTextRecord,
buildUriRecord,
buildMimeRecord,
buildSmartPosterRecord,
buildEmptyRecord,
writeNdef,
formatAndWriteNdef,
getNdefStatus,
scanTagOnce,
makeNdefReadOnly,
readUltralightPages,
// 同步协议辅助(可选)
bytesToHex,
hexToBytes,
createTextRecord,
createUriRecord,
createMimeRecord,
createSmartPosterRecord,
createEmptyRecord,
parseTextPayload,
parseUriPayload,
flattenSmartPoster,
buildNdefMessage,
} from '@/uni_modules/breao-nfcndef'
3. API
3.1 能力与状态
getNfcCapabilities({
success(res) {
// hasHardware / canRead / canWrite / canFormat / canReadUltralightPages / platform
},
})
getNfcStatus({
success(res) {
// enabled / hasHardware / sessionActive
},
})
3.2 会话与标签发现
startNfcSession({
alertMessage: '请将标签贴近手机',
invalidateAfterFirstRead: false,
onTagDiscovered(tag) {
// tag.uid / techList / atqa? / sak?
},
success() {},
fail(err) { console.error(err.errCode, err.errMsg) },
})
onTagDiscovered({ callback(tag) { console.log(tag.uid) } })
offTagDiscovered()
stopNfcSession({ success() {} })
会话参数见 §4。
3.3 NDEF 读 / 写
readNdef({
success(res) {
// res.message.records;Smart Poster 可展平为 text / uri
},
})
// build* 成功回调同时含 record 与 records: [record],单条写入可任选其一
buildTextRecord({ text: 'hello', language: 'zh', success(res) { /* res.record / res.records */ } })
buildUriRecord({ uri: 'https://example.com', success(res) { /* res.record / res.records */ } })
buildMimeRecord({ mimeType: 'application/json', text: '{"id":1}', success(res) { /* res.record / res.records */ } })
buildSmartPosterRecord({ uri: 'https://example.com', text: '标题', language: 'zh', success(res) { /* res.record / res.records */ } })
// 多 record:Text + URI 同条消息写入
buildTextRecord({
text: '资产A',
language: 'zh',
success(t) {
buildUriRecord({
uri: 'https://example.com/a',
success(u) {
writeNdef({ records: [t.record, u.record], success() {} })
},
})
},
})
// 显式擦写:写入 Empty 记录;禁止 writeNdef({ records: [] })(会 9100006,无隐式擦除)
buildEmptyRecord({
success(built) {
writeNdef({ records: built.records, success() {} })
},
})
formatAndWriteNdef({
records: [/* … */],
success() {}, // 空白格式化写入;iOS 可能返回明确不支持码
})
3.4 标签 NDEF 状态
在会话内、标签已贴靠后调用;写入前可查询容量与可写性,避免载荷超限或只读标签写入失败。
getNdefStatus({
success(res) {
// res.isFormatted:是否已格式化为 NDEF
// res.canWrite:当前是否可写
// res.maxSize:可写最大字节数(未格式化时可能为 0)
// res.isReadOnly:是否只读(与 canWrite 互斥语义)
},
fail(err) { console.error(err.errCode, err.errMsg) },
})
3.5 协议辅助(同步)
不依赖 NFC 会话,可在业务侧自组 NfcNdefRecord / NfcNdefMessage 后再 writeNdef:
| 函数 | 说明 |
|---|---|
| bytesToHex | number[] 转大写十六进制字符串 |
| hexToBytes | 十六进制字符串转 number[](忽略空格与冒号) |
| createTextRecord | 同步构建 Text 记录;language 默认 en |
| createUriRecord | 同步构建 URI 记录 |
| createMimeRecord | 同步构建 MIME 记录;payloadHex 优先于 text |
| createSmartPosterRecord | 同步构建 Smart Poster;uri 必填,可选 text / language |
| createEmptyRecord | 同步构建 Empty 记录(显式擦写) |
| parseTextPayload | 解析 Text 记录 payload 为 { text, language } |
| parseUriPayload | 解析 URI 记录 payload 为完整 URI 字符串 |
| flattenSmartPoster | 将 Sp 记录展平并汇总顶层 text / uri |
| buildNdefMessage | 由记录数组构建消息对象(内部调用 flattenSmartPoster) |
3.6 一次性扫描 / 只读 / 页读
scanTagOnce({
timeoutMs: 15000,
autoReadNdef: true,
success(res) {
// 含 tag 信息;autoReadNdef 时含 message
},
})
makeNdefReadOnly({
confirm: true, // 必须为 true,否则 9100012;操作不可逆
success() {},
})
readUltralightPages({
pageOffset: 0,
pageCount: 4,
success(res) {
// 页数据;仅 Android / 鸿蒙部分标签
},
})
4. 可配置项
| 字段 | 位置 | 默认 | 说明 |
|---|---|---|---|
| alertMessage | startNfcSession / scanTagOnce | 无 | iOS 系统弹层提示文案 |
| invalidateAfterFirstRead | startNfcSession | true | 是否首次读后结束会话;读写场景可设 false |
| onTagDiscovered | startNfcSession | 无 | 会话内标签发现回调 |
| debug | startNfcSession | false | 调试日志 |
| text | buildTextRecord | 必填 | NDEF Text 记录正文 |
| language | buildTextRecord | en | 语言代码,如 zh、en |
| uri | buildUriRecord / buildSmartPosterRecord | 必填 | NDEF URI / Smart Poster 目标地址 |
| mimeType | buildMimeRecord | 必填 | MIME 类型,如 text/plain |
| text | buildMimeRecord / buildSmartPosterRecord | 见说明 | MIME 文本载荷;或 Sp 标题 |
| payloadHex | buildMimeRecord | 无 | MIME 十六进制载荷;优先于 text |
| language | buildSmartPosterRecord | en | Sp 标题语言 |
| records | writeNdef / formatAndWriteNdef | 必填非空 | build* 返回的记录数组;可多条;空数组非法 |
| timeoutMs | scanTagOnce | 15000 | 一次性扫描超时毫秒 |
| autoReadNdef | scanTagOnce | true | 发现后是否自动 readNdef |
| confirm | makeNdefReadOnly | 无 | 必须显式 true,否则 9100012 |
| pageOffset | readUltralightPages | 0 | 起始页号 |
| pageCount | readUltralightPages | 4 | 读取页数(每页 4 字节) |
不传参即用默认值。buildEmptyRecord 无额外字段。
5. 完整示例
import {
getNfcStatus,
startNfcSession,
getNdefStatus,
createTextRecord,
createUriRecord,
buildNdefMessage,
writeNdef,
stopNfcSession,
} from '@/uni_modules/breao-nfcndef'
getNfcStatus({
success(st) {
if (!st.enabled) {
console.warn('请开启系统 NFC')
return
}
startNfcSession({
alertMessage: '请将标签贴近手机',
invalidateAfterFirstRead: false,
onTagDiscovered() {
getNdefStatus({
success(nd) {
if (!nd.canWrite) {
console.warn('标签不可写')
return
}
const textRec = createTextRecord('资产A', 'zh')
const uriRec = createUriRecord('https://example.com/asset/a')
const msg = buildNdefMessage([textRec, uriRec])
writeNdef({
records: msg.records,
success() { stopNfcSession({}) },
fail(err) { console.error(err.errCode, err.errMsg) },
})
},
})
},
fail(err) { console.error(err.errCode, err.errMsg) },
})
},
})
6. 权限
请在应用 manifest / 隐私弹窗中按需声明,并说明用于本机与用户贴靠的 NFC 标签之间进行 NDEF 读写。
| 平台 | 权限 | 说明 |
|---|---|---|
| Android | android.permission.NFC | 访问 NFC 硬件读写标签 |
| iOS | NFCReaderUsageDescription | NFC 读取用途说明 |
| iOS | Near Field Communication Tag Reading(Capability) | Xcode 能力开关,启用标签读取 |
| 鸿蒙 | ohos.permission.NFC_TAG | 访问 NFC 标签 |
7. 错误码(910)
| 码 | 含义 |
|---|---|
| 9100001 | 成功 |
| 9100002 | 失败 |
| 9100003 | 会话未开始 |
| 9100004 | 系统 NFC 未开启 |
| 9100005 | 当前无标签 |
| 9100006 | 参数非法(含 records 空数组;擦写请用 buildEmptyRecord) |
| 9100007 | 当前平台不支持 |
| 9100008 | 格式化不支持(如部分 iOS 场景) |
| 9100009 | Ultralight / NTAG 页读不支持 |
| 9100010 | 写入失败 |
| 9100011 | 超时 |
| 9100012 | 只读锁定未显式确认(须 confirm: true) |
| 9100013 | IO 错误 |
| 9100014 | 无 NFC 硬件 |
8. 平台注意
- uni-app x(
.uvue):须对入参使用as XxxOption(见官方 error17);.vue 可直接传对象。须使用 1.2.8+ 并重打自定义基座 - 真机须具备 NFC 并开启;模拟器通常不可用
- iOS 依赖系统 NFC 弹层;详见下方能力矩阵
- Android / 鸿蒙支持空白格式化写入与部分 Ultralight / NTAG 页读
makeNdefReadOnly不可逆,标签写入后将无法再次修改,调用前须confirm: true并提示用户- 读写交替场景建议
invalidateAfterFirstRead: false,避免首次读后会话被系统关闭 - 擦写语义:
writeNdef({ records: [] })/formatAndWriteNdef({ records: [] })一律参数非法(9100006),不会依赖厂商「空数组即擦除」;须buildEmptyRecord得到 Empty 记录后再写入
8.1 能力矩阵
| 能力 | Android | iOS | 鸿蒙 | 说明 |
|---|---|---|---|---|
| 硬件检测 / 开关状态 | 支持 | 支持 | 支持 | getNfcCapabilities / getNfcStatus |
| 前台会话 / 标签发现 / UID | 支持 | 支持 | 支持 | iOS 为系统弹层;alertMessage 主要在 iOS 生效 |
| 读 NDEF(Text / URI / MIME / Sp 展平) | 支持 | 支持 | 支持 | |
| 写 NDEF(含多 record / MIME / Sp / Empty) | 支持 | 支持 | 支持 | 须在会话内贴靠后写入 |
空白标签格式化 formatAndWriteNdef |
支持 | 不支持 | 支持 | iOS 返回明确错误码(如 9100008) |
| Ultralight / NTAG 页读 | 支持 | 不支持 | 支持 | iOS 返回明确错误码(如 9100009) |
makeNdefReadOnly |
支持 | 视系统 / 标签 | 支持 | 不可逆;须 confirm: true |
| 微信小程序 | 不支持 | 不支持 | 不支持 |

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 27
赞赏 0
下载 12642692
赞赏 1951
赞赏
京公网安备:11010802035340号