NFC(Near Field Communication,近场通信) 是一种短距离高频无线通信技术,允许电子设备在近距离内进行非接触式数据交换。日常使用的饭卡、银行卡、公交卡、门禁卡等等都是基于 NFC 技术实现的。
App Scheme 是一种 URL 协议方案,允许通过特定格式的 URL 直接唤起移动应用程序,并执行特定操作或跳转到特定页面。
scheme://[host]/[path]?[query]
例如:
weixin:// - 唤起微信应用alipays:// - 唤起支付宝应用myapp://home/detail?id=123 - 打开自定义应用的详情页将 NFC 与 Scheme 结合,可以实现"一触即达"的用户体验:
1. 生成小程序 URL Scheme
↓
2. 写入 NFC 标签(NDEF 格式)
↓
3. 用户触碰 NFC 标签
↓
4. 手机读取 URL Scheme
↓
5. 自动唤起小程序
/**
* 初始化 NFC 适配器
*/
initNFCAdapter(): Promise<any> {
return new Promise((resolve, reject) => {
try {
this.nfcAdapter = Taro.getNFCAdapter()
console.log('NFC adapter initialized successfully')
resolve(this.nfcAdapter)
} catch (error) {
console.error('Failed to initialize NFC adapter:', error)
reject(error)
}
})
}
/**
* 开始扫描 NFC 标签
*/
startDiscovery(): Promise<any> {
return new Promise(async (resolve, reject) => {
try {
// 如果还没有初始化适配器,先初始化
if (!this.nfcAdapter) {
await this.initNFCAdapter()
}
// 注册标签发现监听
this.nfcAdapter.onDiscovered(this.onDiscoveredHandler)
// 开始扫描
this.nfcAdapter.startDiscovery({
success: (res: any) => {
console.log('NFC discovery started successfully')
this.isDiscovering = true
resolve(res)
},
fail: (err: any) => {
const errorCodeMap = {
13000: '设备不支持NFC',
13001: '系统NFC开关未打开',
}
reject(errorCodeMap[err.errCode] ?? err.errMsg)
},
})
} catch (error) {
reject(error)
}
})
}
/**
* 内部发现处理函数
*/
private onDiscoveredHandler = (res: any): void => {
console.log('NFC tag discovered:', res)
// 构造标签信息
const tag: NFCTag = {
techs: res.techs || [],
messages: res.messages,
id: res.id,
}
// 保存标签 ID(转为 16 进制字符串)
if (res.id) {
this.lastDiscoveredTagId = this.buff2hex(res.id)
}
// 检测标签
if (this.connectedTagId && this.lastDiscoveredTagId !== this.connectedTagId) {
console.error('Tag conflict detected')
// 提示用户移除其他标签
return
}
// 自动处理不同技术类型
if (res.techs.includes(this.nfcAdapter.tech.ndef)) {
this.currentNdef = this.nfcAdapter.getNdef()
}
if (res.techs.includes(this.nfcAdapter.tech.nfcA)) {
this.currentNfcA = this.nfcAdapter.getNfcA()
}
// 调用用户设置的回调
if (this.discoverHandler) {
this.discoverHandler(tag)
}
}
/**
* 写入 NDEF 消息
* @param config NDEF 消息配置(包含 URL Scheme)
*/
writeNdefMessage(config: NdefMessageConfig): Promise<any> {
return new Promise(async (resolve, reject) => {
try {
if (!this.currentNdef) {
reject(new Error('No NDEF tag available'))
return
}
// 连接标签
if (!this.connectedTagId) {
await this.connectNdef()
await sleep(200)
}
this.currentNdef.writeNdefMessage({
...config,
success: (res: any) => {
console.log('NDEF message written successfully')
resolve(res)
},
fail: (err: any) => {
if (err.errCode === 13017) {
this.closeNdef()
reject(new Error('NFC读写操作失败,请保持标签靠近设备'))
} else {
reject(err)
}
},
})
} catch (error) {
reject(error)
}
})
}
btw: 调试开发时使用的NFC标签物料就是支付宝的碰一下,影视飓风出过一期视频 直播5年,影视飓风再造新场地?? 亦是如此。