解决微信小程序ios用户获取mac地址问题,uuid转mac地址

问题描述:

最近用到小程序的蓝牙,设备通过安卓机测试以后以为没有问题了(没有苹果🥲🥲🥲!),后续发现在iPhone上不行。AI了一下,找到了答案,但是浪费了很多时间在小问题上。

在Android平台上,获取到的deviceId为设备的MAC地址;而在iOS平台上,获取到的deviceId为设备的UUID。

实现效果:

在这里插入图片描述

解决方案:

 uni.getBluetoothDevices({
        success(res) {
          if (res.devices.length > 0) {
            res.devices.forEach((v) => {
              var val = v.localName || v.name;
              if (val.indexOf("RF") == -1) return;
              // 查找到名称包括RF的设备
              // serviceData 是对象,需要把值取出来才能用Uint8Array转化
              let serviceData = v.serviceData;
              if (typeof serviceData === "object" && serviceData !== null) {
                const serviceDataKeys = Object.keys(serviceData);
                const serviceDataBuffer =
                  serviceDataKeys.length && serviceData[serviceDataKeys];
                v.uuidObj = parseServiceData(serviceDataBuffer);
              } else {
                v.uuidObj = {};
              }
            });
          }
     },
});
      
function parseServiceData(buffer) {
  // console.log("buffer====", buffer);
  if (!(buffer instanceof ArrayBuffer)) return {};
  const view = new Uint8Array(buffer);
  if (buffer.byteLength === 14) {
    return {
      macAddress: Array.from(view.slice(0, 6))
        .map((b) => b.toString(16).padStart(2, "0"))
        .join(":")
        .toUpperCase(),
      major: (view[7] << 8) | view[6], // 0x0708 → 1800
      minor: (view[9] << 8) | view[8], // 0x0506 → 1286
      txPower: new Int8Array([view[10]])[0], // 0 → 0 dBm
      advertisingInterval: (view[12] << 8) | view[11], // 0x03E8 → 1000 ms
      batteryLevel: view[13], // 0x51 → 81%
    };
  } else if (buffer.byteLength === 6) {
    return {
      macAddress: Array.from(view.slice(0, 6))
        .reverse()
        .map((b) => b.toString(16).padStart(2, "0"))
        .join(":")
        .toUpperCase(),
    };
  }
}

关键问题:

  1. 确定厂商在蓝牙设备中配置了mac信息。蓝牙广播收到的蓝牙信息中的serviceData 和advertisData是什么?
字段作用包含关系示例用途
advertisData通用广播信息(设备名、厂商数据等)包含 serviceData 和其他字段设备发现、基础信息传递
serviceData特定服务相关的数据是 advertisData 的子集心率数据、信标标识、传感器数据
  1. 确定advertisData/serviceData数据解析格式。看不懂就AI解释一下。
    在这里插入图片描述
  2. 通过getBluetoothDevices获取到的蓝牙设备信息如图。advertisData是个ArrayBuffer类型。serviceData:是个ArrayBuffer类型的对象,key值是:00001803-0000-1000-8000-00805F9B34FB,因为mac信息在serviceData中,所以直接解析serviceData的值。serviceData是个对象,需要将value值(ArrayBuffer)取出来转Uint8Array。注意转化为Uint8Array后,其长度不变。比如原来长度,转化后也是14。serviceData: Proxy(Object) {00001803-0000-1000-8000-00805F9B34FB: ArrayBuffer(14)} 。注意不同设备serviceData的字节长度不同,需要区别处理。
const serviceDataKeys = Object.keys(serviceData);
const serviceDataBuffer =serviceDataKeys.length && serviceData[serviceDataKeys];
v.uuidObj = parseServiceData(serviceDataBuffer);

ArrayBuffer是JavaScript中处理二进制数据的核心对象,它表示一段固定长度的原始二进制数据缓冲区。ArrayBuffer本身不能直接读写,必须通过TypedArray(如Uint8Array、Int16Array等)或DataView来操作数据。其核心特性包括固定长度、内存直接操作以及高效处理二进制数据。

在这里插入图片描述
在这里插入图片描述

  1. 一般mac占6个字节,取转化为Uint8Array后的数组对应位置的值转化为16进制后就能拿到mac值了。
macAddress: Array.from(view.slice(0, 6))
        .map((b) => b.toString(16).padStart(2, "0"))
        .join(":")
        .toUpperCase()

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值