1950年世界杯_中国队如何进世界杯 - mbkbl.com

1950年世界杯_中国队如何进世界杯 - mbkbl.com

shape
  • Home
  • 世界杯参赛队伍
  • 微信小程序NFC监听、读取;Scheme唤起小程序

微信小程序NFC监听、读取;Scheme唤起小程序

  • 2025-07-03 22:12:25
  • admin

微信小程序NFC监听、读取;Scheme唤起小程序

一个需求,要NFC封签唤起小程序,期望用小程序来做一些管理工作。又因为NFC的可复制性过于便捷,还要做加密处理,防止被复制盗用。

业务流程

Scheme唤起小程序

小程序获取NFC实例、开启监听(仅支持安卓)

监听到NFC实例,读取卡片信息

监听到NFC实例,读取卡片内容

处理业务逻辑

本文主要围绕1234开展。

Scheme唤起小程序

Scheme唤起小程序,是微信官方支持的一个场景。NFC封签只要写入了Scheme,就能唤起。(写入不难,微信里搜一下NFC,就有很多小程序可以用)

主要是要先生成Scheme,需要小程序申请生成Scheme接口。申请到了,用相应接口生成就好。简单贴一下需要的传参。

js

体验AI代码助手

代码解读

复制代码

//请求地址

//POST https://api.weixin.qq.com/wxa/generatenfcscheme?access_token=ACCESS_TOKEN

{

"jump_wxa": {

"path": "非必填, 请输入字符串, 例如'a'",

"query": "非必填, 请输入字符串, 例如'a'",

"env_version": "非必填, 请输入字符串, 例如'a'"

},

"model_id": "必填, 请输入字符串, 例如'a'",

"sn": "非必填, 请输入字符串, 例如'a'"

}

小程序获取NFC实例、开启监听

js

体验AI代码助手

代码解读

复制代码

onLoad(options) {

this.initialNFC()

}

initialNFC() {

// 获取NFC实例

const nfc = wx.getNFCAdapter()

this.setData({ nfcAdapter: nfc})

const _this = this

nfc.startDiscovery({

success(res) {

console.log('NFC读取功能已开启')

nfc.onDiscovered(_this.discoverHandler)

},

fail(err) {

if (!err.errCode) {

return console.log('微信(IOS)不支持NFC识别,请使用微信(安卓)')

}

}

})

},

// 监听方法,监听到NFC实例,读取卡片信息,res里就是卡片信息,不过需要转换一下

discoverHandler(res) {

const { nfcAdapter:adapter } = this.data

const str = this.buf2hex(res.id)

if (str) {

// 这里拿到UID,可以做一点业务逻辑了

}

},

// ArrayBuffer转16进制

buf2hex(arrayBuffer) {

return Array.prototype.map.call(new Uint8Array(arrayBuffer), x => ('00' + x.toString(16)).slice(-2)).join('');

},

读取卡片内容

有卡片信息(物理载体)还不够,还需要卡片中的内容(载体里写入的数据)。

(之所以走到这一步,是因为Scheme唤起小程序,会在onLoad(options)方法中的 options里可以拿到写在Scheme上的参数,在小程序初次加载时被动获取的)

一旦监听开启,用户刷一下NFC卡,能拿到的是卡片信息。我们业务逻辑中,需要用到 写在Scheme上的参数 和 卡片id。

也不能告诉用户,麻烦你关掉小程序再打开,就能正确展示页面内容了。

在这里隆重地吐槽一下,安卓和微信,这两个残疾人,一个能用一半,要是能拼起来我就没那么多事情了。

安卓:可以读取NFC,但是Scheme一旦唤起页面,若手机保持在小程序页面,即使读取到Scheme,也不会再唤起小程序

IOS:不可以读取NFC,但是每次检测到Scheme都会垂询用户,是否要重新唤起小程序

经试验,无法读取卡片内容,下面是翻车现场

在回调函数中,根据返回的res.techs字段匹配到卡片支持的NFC标准 见下图

支持的技术标准是"NFC-A"、"MIFARE Ultralight"、"NDEF"。

点击查看文章→NfcA/NfcB/IsoDep/Ndef/Mifare 都是些什么玩意?

微信官方文档说明约等于没说,也没有示例代码。

adapter中的方法 参数

js

体验AI代码助手

代码解读

复制代码

getIsoDep: ƒ ()

getMifareClassic: ƒ ()

getMifareUltralight: ƒ ()

getNdef: ƒ ()

getNfcA: ƒ ()

getNfcB: ƒ ()

getNfcF: ƒ ()

getNfcV: ƒ ()

offDiscovered: ƒ ()

onDiscovered: ƒ ()

startDiscovery: ƒ ()

stopDiscovery: ƒ ()

tech: {ndef: "NDEF", nfcA: "NFC-A", nfcB: "NFC-B", isoDep: "ISO-DEP", nfcF: "NFC-F", …}

_nfcA: gme {techType: "NFC-A"}

尝试1 getMifareClassic,失败。

"MIFARE Classic",M1是加密卡,有密钥、分扇区,所以一定要问清楚写入卡数据的同学,让他提供扇区、第三方密钥。

js

体验AI代码助手

代码解读

复制代码

// 连接不成功,先放着

// 读取数据

readNFC(res) {

const { nfcAdapter:adapter } = this.data

// res.techs 只有三个"NFC-A"、"MIFARE Ultralight"、"NDEF"。

// 没有"MIFARE Classic",所以关闭这个判断

// if (res.techs.includes(adapter.tech.mifareClassic)) {

// }

console.log('发现' + adapter.tech.mifareClassic + '卡');

let mifareClassic = adapter.getMifareClassic();

debugger

mifareClassic.connect({

success: res => {

console.log("设备已连接", res)

console.log("开始拼接验密指令。。。");

debugger

// var arr = [0x60, 0x04, 0x11, 0x22, 0x33, 0x44, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];

let shanqu = [0x60, 0x00] //查询扇,后边需要拼接上秘钥,

let newCardPsd = new Uint8Array(cardPsd) //转换命令格式

let arr = [...shanqu,...newCardPsd] //把查询扇区的初始跟查询ID拼接到一起

var arrayBuffer = new Uint8Array(arr).buffer

console.log("解密指令为:", arrayBuffer);

mifareClassic.transceive({

data: arrayBuffer,

success: function (res) {

console.log('发送数据并解密成功, 接收数据如下:', res);

},

fail: function (err) {

console.log('发送数据失败A', err);

wx.showToast({

title: 'nfc失败!',

icon:'error'

})

}

})

},

fail: function (err) {

debugger

console.log('设备连接失败', err);

}

})

mifareClassic.isConnected({

success: function (isConnected) {

debugger

console.log('成功连接', isConnected);

var arr01 = [0x30, 0x04];

var arrayBuffer01 = new Uint8Array(arr01).buffer

console.log('arrayBuffer02',arrayBuffer01);

var strList = {

orgId: '',

orgUserId: ''

}

mifareClassic.transceive({

data: arrayBuffer01,

success: function (res) {

console.log('读取数据:', res);

wx.showLoading({

title: '识别中...',

mask: true,

success: (res) => {},

fail: (res) => {},

complete: (res) => {},

})

const arrayBuffer = res.data // 获取通讯数据,类型为ArrayBuffer

const data16 = that.buf2hex(arrayBuffer) // ArrayBuffer转16进制

const requestData = that.hexToStr(data16) // 16进制转字符串

let arr = requestData.split('')

let str = ''

arr.forEach((item,index)=>{

console.log(item,item.length);

if(item>=0){

str += item

}

})

strList.orgId = str

console.log('requestData',str,'arr',arr)

},

fail: function (err) {

console.log('失败', err);

wx.showToast({

title: 'nfc失败!',

icon:'error'

})

}

})

var arr02 = [0x30, 0x05];

var arrayBuffer02 = new Uint8Array(arr02).buffer

console.log('arrayBuffer02',arrayBuffer02);

mifareClassic.transceive({

data: arrayBuffer02,

success: function (res) {

debugger

console.log('读取数据:', res);

wx.showLoading({

title: '识别中...',

mask: true,

success: (res) => {},

fail: (res) => {},

complete: (res) => {},

})

const arrayBuffer = res.data // 获取通讯数据,类型为ArrayBuffer

const data16 = that.buf2hex(arrayBuffer) // ArrayBuffer转16进制

const requestData = that.hexToStr(data16) // 16进制转字符串

let arr = requestData.split('')

let str = ''

arr.forEach((item,index)=>{

console.log(item,item.length);

if(item>=0){

str += item

}

})

strList.orgUserId = str

console.log('requestData2',strList)

that.getNfcCardList(strList)

},

fail: function (err) {

console.log('失败', err);

wx.showToast({

title: 'nfc失败!',

icon:'error'

})

}

})

}

});

},

方式一报错,这个报错是对的,因为咱们确实不支持M1。

尝试2 getNdef

失败方式二

js

体验AI代码助手

代码解读

复制代码

// 读取数据

readNFC(res) {

const { nfcAdapter:adapter } = this.data

console.log('res.techs', res.techs)

// 获取 NDEF 类型的 NFC 适配器

const ndefAdapter = adapter.getNdef()

// 连接到 NFC 标签

ndefAdapter.connect({

success() {

console.log('已连接到 NFC 标签');

// 在这里可以进行与 NFC 标签的通信操作

// 例如读取 NDEF 记录、写入 NDEF 记录等

// 断开与 NFC 标签的连接

ndefAdapter.close({

success() {

console.log('已断开与 NFC 标签的连接');

},

fail(err) {

console.error('断开与 NFC 标签的连接失败:', err);

}

});

},

fail(err) {

console.error('连接到 NFC 标签失败:', err);

}

});

},

方式二报错

尝试3 getNfcA

NFC-A 类型的 NFC 适配器

js

体验AI代码助手

代码解读

复制代码

// 读取数据

readNFC(res) {

const { nfcAdapter:adapter } = this.data

console.log('res.techs', res.techs)

debugger

// 获取 NFC-A 类型的 NFC 适配器

const nfcAAdapter = adapter.getNfcA()

// 连接到 NFC 标签

nfcAAdapter.connect({

success() {

console.log('已连接到 NFC 标签');

// 在这里可以进行与 NFC 标签的通信操作

// 例如发送读取命令,获取数据等

// 断开与 NFC 标签的连接

nfcAAdapter.close({

success() {

console.log('已断开与 NFC 标签的连接');

},

fail(err) {

console.error('断开与 NFC 标签的连接失败:', err);

}

});

},

fail(err) {

console.error('连接到 NFC 标签失败:', err);

}

});

},

连接到 NFC 标签失败: {errMsg: "connect:fail:system internal error: NFC service died", errCode: 13017, errno: 1504210}

尝试4 gtIsoDep

js

体验AI代码助手

代码解读

复制代码

const isoDepAdapter = adapter.getIsoDep();

// 连接到 NFC 标签

isoDepAdapter.connect({

success() {

console.log('已连接到 NFC 标签');

// 在这里可以进行与 NFC 标签的通信操作

// 例如发送 APDU 指令,读取或写入数据等

// 断开与 NFC 标签的连接

isoDepAdapter.close({

success() {

console.log('已断开与 NFC 标签的连接');

},

fail(err) {

console.error('断开与 NFC 标签的连接失败:', err);

}

});

},

fail(err) {

console.error('连接到 NFC 标签失败:', err);

}

});

尝试5 getMifareUltralight

js

体验AI代码助手

代码解读

复制代码

const mifareUltralightAdapter = adapter.getMifareUltralight()

// 连接到 NFC 标签

mifareUltralightAdapter.connect({

success() {

console.log('已连接到 NFC 标签');

// 在这里可以进行与 NFC 标签的通信操作

// 例如读取 NDEF 记录、写入 NDEF 记录等

// 断开与 NFC 标签的连接

mifareUltralightAdapter.close({

success() {

console.log('已断开与 NFC 标签的连接');

},

fail(err) {

console.error('断开与 NFC 标签的连接失败:', err);

}

});

},

fail(err) {

console.error('连接到 NFC 标签失败:', err);

}

});

参考文档:

参考博客一

参考博客二

待参考博客三

Previous Post
半条命alyx必须用vr吗
Copyright © 2088 1950年世界杯_中国队如何进世界杯 - mbkbl.com All Rights Reserved.
友情链接