微信小程序读取IC卡失败?

微信小程序读取IC卡失败,adapter.onDiscovered未读取到卡,该IC卡为加密卡,该如何识别?

let _this = this
let adapter = wx.getNFCAdapter()
adapter.startDiscovery({
  success: (e) => {
      console.log('开始贴卡了', e)
      // 监听 NFC Tag
      adapter.onDiscovered(function(res) {
          console.log('读到卡片了', res);
      })
  }
})
阅读 2.4k
avatarAI BotBETA

回答

微信小程序读取IC卡失败可能有多种原因。根据你提供的信息和代码,以下是一些可能的原因和解决方案:

  1. IC卡不支持NFC

    • 并非所有的IC卡都支持NFC功能。如果你的IC卡不支持NFC,那么微信小程序将无法读取它。
    • 解决方案:确认你的IC卡是否支持NFC功能。你可以尝试使用其他支持NFC的卡片进行测试,看看是否能成功读取。
  2. 微信小程序NFC权限和配置

    • 确保你的微信小程序已经在app.json中声明了NFC权限,并且用户已经授予了NFC权限。
    • 解决方案:检查app.json中的权限声明,并确保用户已经同意使用NFC功能。
  3. 代码逻辑问题

    • 你的代码逻辑本身看起来没有问题,但是可能有一些细节需要注意。例如,adapter.onDiscovered是一个事件监听器,它会在发现NFC标签时被触发。确保这个监听器在adapter.startDiscovery成功之后被正确设置。
    • 解决方案:检查代码逻辑,确保事件监听器在正确的时机被设置,并且没有其他的错误导致监听器无法正常工作。
  4. 设备兼容性

    • 不同的设备和操作系统版本可能对NFC的支持有所不同。虽然你能够读取华为手表模拟卡,但这并不意味着所有NFC卡片都能被读取。
    • 解决方案:尝试在不同的设备和操作系统版本上进行测试,看看问题是否仍然存在。
  5. 其他干扰因素

    • 有时候,其他NFC设备或磁场干扰可能会影响NFC的读取。
    • 解决方案:确保在读取NFC卡片时,没有其他NFC设备或磁场干扰。

综上所述,你需要检查IC卡是否支持NFC、微信小程序的NFC权限和配置、代码逻辑、设备兼容性以及其他可能的干扰因素。如果问题仍然存在,你可能需要更详细地调试代码或寻求微信小程序的官方支持。

1 个回答

我把具体流程写一下

  1. 确保设备支持NFC
    确认你的设备支持NFC,并且NFC功能已开启。
  2. 微信小程序权限设置
    可以参考这里申请,点击以下绿色文字链接查看文档
    NFC标签打开小程序
    在微信小程序的 app.json 文件中,添加NFC权限配置:

    {
      "permission": {
        "scope.userLocation": {
          "desc": "你的位置信息将用于小程序位置接口的效果展示"
        },
        "scope.nfc": {
          "desc": "你的NFC权限将用于小程序NFC功能的实现"
        }
      }
    }
  3. 获取NFC适配器实例
    使用 wx.getNFCAdapter() 获取NFC适配器实例。
  4. 监听NFC标签
    使用 adapter.onDiscovered 监听NFC标签的发现事件。
  5. 连接并认证IC卡

    • 获取 MifareClassic 实例并连接。
    • 使用正确的密钥进行认证。默认密钥通常是 FFFFFFFFFFFF,但在实际应用中,可能需要使用卡片厂商提供的密钥。
  6. 处理数据传输

    • 认证成功后,发送读取指令读取数据。

完整代码

IC卡的类型是有M1卡,CPU卡,UID卡,FUID卡,我提供的是支持M1类型的
以下是一个完整的示例代码,在微信小程序中读取加密IC卡:

let _this = this;
let adapter = wx.getNFCAdapter();

adapter.startDiscovery({
  success: (e) => {
    console.log('开始贴卡了', e);
    // 监听 NFC Tag
    adapter.onDiscovered(function(res) {
      console.log('读到卡片了', res);
      let mifareClassic = adapter.getMifareClassic();
      mifareClassic.connect({
        success: (res) => {
          console.log('设备已连接', res);
          // 认证指令: 0x60(KEYA) + 扇区编号 + UID + 12位HEX密钥
          let cmd = new Uint8Array([0x60, 0x00, ..._this.hexStringToByteArray('FFFFFFFFFFFF')]);
          mifareClassic.transceive({
            data: cmd.buffer,
            success: (res) => {
              console.log('认证成功, 接收数据如下:', res);
              // 读取数据
              let readCmd = new Uint8Array([0x30, 0x00]);
              mifareClassic.transceive({
                data: readCmd.buffer,
                success: (res) => {
                  console.log('读取数据:', res);
                },
                fail: (err) => {
                  console.log('读取数据失败', err);
                }
              });
            },
            fail: (err) => {
              console.log('认证失败', err);
            }
          });
        },
        fail: (err) => {
          console.log('连接失败', err);
        }
      });
    });
  }
});

// 辅助函数:将十六进制字符串转换为字节数组
_this.hexStringToByteArray = function(hexString) {
  let result = [];
  for (let i = 0; i < hexString.length; i += 2) {
    result.push(parseInt(hexString.substr(i, 2), 16));
  }
  return result;
};
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏