因工作需要,需要实现通过NFC标签拉起微信小程序,小程序文档:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/NFC.html
1、 申请【NFC调起小程序】能力
1.1 在小程序后台 【行为能力->硬件设备】 添加设备;
注:添加设备时需要填写的品牌名称、生产厂商我填的是小程序基本信息中所归属的公司(我填其他的会审核不通过);
1.2 审核通过后给设备申请设备能力;
注:一机一码model_id能使用多次,一型一码model_id只能使用一次;
2、 申请 URL Schem;
2.1 把申请到的schema url写入NFC标签中;
注:网上有一些能直接识别NFC标签并写入schema url的小程序可直接使用;由于我的需求是打开小程序并能区分每个NFC标签,因此我使用的是一机一码,并自己实现写入schema url的功能;
3、实现写入schema url功能;
3.1 获取NFC实例并监听 Tag;
this.nfc = wx.getNFCAdapter()
this.listener = (res)=> {
const id = new Uint8Array(res.id)
// 回调函数中res有3个属性,id,techs,messages,因为我们要获取NFC Tag,所以只处理id
// 返回的id属性值是一个ArrayBuffer类型
// 使用 new Uint8Array处理返回一个数组
this.connectNfc(res)
}
// 绑定监听 NFC Tag
this.nfc.onDiscovered(this.listener)
// 开始监听
this.nfc.startDiscovery({
fail(err) {
console.log('failed to discover:', err)
}
})
connectNfc(res){
// 连接NFC
const NFCTab = this.nfc.getNdef()
NFCTab.connect({
success: () => {
// 处理我们想要的参数
},
fail: error => {
wx.showToast({
title: '连接设备失败',
icon: 'error'
})
console.log("nfc-getNdef-error:",error)
}
})
},
3.1 生成schema url并写入NFC标签;
async getPayloadUrl(){
// 获取小程序 scheme url
if(!this.data.nfcId){
return wx.showToast({
title: '请把NFC标签对准NFC感应区',
icon:"none"
})
}
let res = await getAccessToken();//通过接口获取access_token
let {wxPath,query,modelId,sn} = this.data;
if(res.result_code == 'success'){
let access_token = res.access_token;
let params = {
"jump_wxa":{ path:wxPath,query },
"model_id":modelId,
}
if(sn){
params.sn = sn
}
wx.request({
url: 'https://api.weixin.qq.com/wxa/generatenfcscheme?access_token='+access_token,
method:"POST",
data:params,
success: res => {
if(res.data.openlink){
//写入NFC标签
this.nfcWriteNdefMessage(res.data.openlink)
}else{
console.log(res.data.errmsg)
}
},
fail: err => {
console.log(999,err)
}
})
}
},
nfcWriteNdefMessage(loadUrl){
const records = [
{
id: this.str2ab('mini-ios'),
tnf: 1,
type: this.str2ab('U'),
payload: this.str2ab(loadUrl, [0])
},
{
id: this.str2ab('mini-android'),
tnf: 4,
type: this.str2ab('android.com:pkg'),
payload: this.str2ab('com.tencent.mm')
}
]
this.setData({
schemaUrl:loadUrl
})
const NFCTab = this.nfc.getNdef()
// 执行写入
NFCTab.writeNdefMessage({
records: records,
success: res => {
wx.showToast({
title: '写入成功',
})
console.log(res);
},
fail: error => {
wx.showToast({
title: '写入失败,请确保nfc标签卡片贴着手机',
icon:"error"
})
console.error(error);
},
});
},
str2ab (text, extraBytes) {
const uriStr = encodeURIComponent(text)
const bytes = []
for (let i = 0; i < uriStr.length; i++) {
const code = uriStr.charAt(i)
if (code === '%') {
const hex = uriStr.slice(i + 1, i + 3)
const hexVal = parseInt(hex, 16)
bytes.push(hexVal)
i += 2
} else {
bytes.push(code.charCodeAt(0))
}
}
if (extraBytes) {
bytes.unshift(...extraBytes)
}
return new Uint8Array(bytes).buffer
},