空白nfc卡(如ntag213/215)需先formattag格式化为ndef格式,再调用writendefmessage写入,否则因协议不匹配直接失败;uid区硬件只读不可写,ndef载荷区容量有限且中文需按规范编码。

纯 plus.nfc.writeNdefMessage() 在真机上大概率写不进空白卡——不是你数据错了,是安卓系统根本没把写请求路由给标签。
为什么 writeNdefMessage 总失败?
空白 NFC 卡(如 NTAG213/215)出厂时通常没有 NDEF 格式结构,plus.nfc.writeNdefMessage() 会直接报错或静默失败,因为它只对已格式化为 NDEF 的标签生效。系统看到“非 NDEF 卡”,就拒绝写入,连权限校验都跳过。
- 错误现象:
java.lang.SecurityException: Permission Denial或无任何回调、无日志 - 真实原因:不是缺
WRITE_TAG权限(该权限在 uni-app 中无法声明),而是卡未格式化,协议层不匹配 - 验证方法:用手机装
NFC Tools扫卡,若显示 “Not formattable” 或 “No NDEF message”,就是这张卡还没准备好
必须先 formatTag,再写
对空白卡,得走两步:先格式化成 NDEF 可写状态,再写入内容。uni-app 的 plus.nfc 提供了 formatTag() 方法,但需注意调用时机和前置条件:
- 必须在
plus.nfc.onNdefMessage或discovered回调里调用,不能提前硬写 - 调用前确保
plus.nfc.startNdefDispatch()已激活(页面onShow中执行) - 格式化成功后,要主动触发一次重新发现(部分机型需短暂移开再靠近)才能进入可写状态
- 示例片段:
plus.nfc.onNdefMessage((res) => { // 检查是否为空白卡:res.records.length === 0 且 res.tag 有效 if (res.records.length === 0 && res.tag) { plus.nfc.formatTag(res.tag, () => { console.log('格式化成功'); // 此处立即构造 NDEF 并 writeNdefMessage const record = { tnf: 1, type: 'T', payload: 'Hello' }; plus.nfc.writeNdefMessage([record], () => { console.log('写入成功'); }, (err) => { console.error('写入失败', err); }); }, (err) => { console.error('格式化失败', err); }); } });
绕过 NDEF 直接写 UID 区?不推荐
有人想用原生反射调 tag.getId() + 自定义指令写入 UID 所在扇区——这在 NTAG 系列上不可行:UID 是只读物理字段,硬件强制锁定,任何写操作都会失败或损坏标签。MIFARE Classic 类卡片虽可写其他扇区,但需要密钥认证,plus.nfc 不提供 auth 接口,强行调用会抛 IOException: Transceive failed。
- 真正能安全写的,只有 NDEF 载荷区(即 formatTag 后开放的那块)
- NTAG213 最大可用 NDEF 容量约 137 字节;NTAG215 是 483 字节;别超限,否则写入中断无提示
- 写入含中文时,payload 必须按 NDEF 文本记录规范组装:首字节为语言码长度(通常 2),接着
"zh",再接 UTF-8 编码字节——直接传字符串会乱码
真机调试三件套缺一不可
即使代码全对,以下任一条件不满足,写操作就完全没反应:
- 手机 NFC 开关已打开(不止是“支付用”,得设为“开启并允许所有应用使用”)
- App 处于前台且屏幕常亮(
plus.android.keepScreenOn(true)建议加在onShow,onHide关闭) -
manifest.json中同时声明:"permissions": ["<uses-permission android:name='\"android.permission.NFC\"/'>"]</uses-permission>和"usesFeatures": ["android.hardware.nfc"]
最易忽略的是:打包后未在 Android 设置中手动授予 NFC 权限(部分厂商 ROM 会隐藏该开关),此时 adb 查 dumpsys nfc 会显示 mIsEnabled: false,而非代码问题。











