蓝牙 (Bluetooth)

微信小程序将各平台的蓝牙能力通过统一的接口封装提供给开发者使用。利用微信小程序的蓝牙接口,开发者可以通过无线方式与其他蓝牙设备交换数据。

1. 蓝牙能力概述

蓝牙技术规范由蓝牙技术联盟 (Bluetooth Special Interest Group, SIG) 制定,开发者可以在其官方网站获取到详细的技术文档。

目前蓝牙最为普遍使用的有两种规格:

  • 蓝牙基础率/增强数据率 (Bluetooth Basic Rate/Enhanced Data Rate, BR/EDR): 也称为经典蓝牙。常用在对数据传输带宽有一定要求的场景上,比如需要传输音频数据的蓝牙音箱、蓝牙耳机等;
  • 蓝牙低功耗 (Bluetooth Low Energy, BLE): 从蓝牙 4.0 起支持的协议,特点就是功耗极低、传输速度更快,常用在对续航要求较高且只需小数据量传输的各种智能电子产品中,比如智能穿戴设备、智能家电、传感器等,应用场景广泛。

2. 微信小程序中的蓝牙能力

在微信小程序中,要使用蓝牙能力(Beacon 除外)必须首先调用 wx.openBluetoothAdapter 初始化蓝牙适配器模块,其生效周期为调用 wx.openBluetoothAdapter 至调用 wx.closeBluetoothAdapter 或微信小程序被销毁为止。只有在微信小程序蓝牙适配器模块生效期间,开发者才能够正常调用蓝牙相关的微信小程序 API,并收到蓝牙模块相关的事件回调(绑定监听不受此限制)。

微信小程序对蓝牙支持情况如下:

  • 经典蓝牙:iOS 因系统限制暂无法提供,安卓目前已在规划中。
  • 蓝牙低功耗 (BLE)
    • 主机模式:基础库 1.1.0(微信客户端 iOS 6.5.6,Android 6.5.7)开始支持。
    • 从机模式:基础库 2.10.3 开始支持。
    • 蓝牙信标 (Beacon):基础库 1.2.0 开始支持。

蓝牙低功耗 (Bluetooth Low Energy, BLE)

主机模式:基础库 1.1.0(微信客户端 iOS 6.5.6,Android 6.5.7)开始支持。

从机模式:基础库 2.10.3 开始支持。

蓝牙低功耗是从蓝牙 4.0 起支持的协议,与经典蓝牙相比,功耗极低、传输速度更快,但传输数据量较小。常用在对续航要求较高且只需小数据量传输的各种智能电子产品中,比如智能穿戴设备、智能家电、传感器等,应用场景广泛。

1. 角色/工作模式

蓝牙低功耗协议给设备定义了若干角色,或称工作模式。微信小程序蓝牙目前支持的有以下几种:

1) 中心设备/主机 (Central)

中心设备可以扫描外围设备,并在发现有外围设备存在后与之建立连接,之后就可以使用外围设备提供的服务(Service)。

一般而言,手机会担任中心设备的角色,利用外围设备提供的数据进行处理或展示等等。微信小程序提供低功耗蓝牙接口是默认设定手机为中心设备的。

2) 外围设备/从机 (Peripheral)

外围设备一直处于广播状态,等待被中心设备搜索和连接,不能主动发起搜索。例如智能手环、传感器等设备。

如果外围设备广播时被设置为不可连接的状态,也被称为广播模式 (Broadcaster),常见的例子是蓝牙信标 (Beacon) 设备。

注意

微信小程序中,蓝牙设备可以同时处于主机和从机模式。在安卓设备上,只需要调用 wx.openBluetoothAdapter 初始化一次蓝牙适配器;而在 iOS 设备上,需要分别使用两种不同的 mode 参数分别初始化中心设备和外围设备的蓝牙适配器。建议统一对于主机和从机模式分别进行一次初始化。wx.closeBluetoothAdapter 会同时关闭两种模式的蓝牙适配器。

2. 通信协议

在两个蓝牙低功耗设备建立连接之后,双方的数据交互是基于 GATT (Generic Attribute Profile) 规范,根据该规范可以定义出一个个配置文件 (Profile),描述该蓝牙设备提供的服务 (Service)。

在整个通信过程中,有几个最主要的概念:

  • 配置文件 (Profile): Profile 是被蓝牙标准预先定义的一些 Service 的集合,并不真实存在于蓝牙设备中。如果蓝牙设备之间要相互兼容,它们只要支持相同的 Profile 即可。一个蓝牙设备可以支持多个 Profile。
  • 服务 (Service): Service 是蓝牙设备对外提供的服务,一个设备可以提供多个服务,比如电量信息服务、系统信息服务等。每个服务由一个 UUID 唯一标识。
  • 特征 (Characteristic): 每个 Service 包含 0 至多个 Characteristic。比如,电量信息服务就会有个 Characteristic 表示电量数据。Characteristic 包含一个值 (value)和 0 至多个描述符 (Descriptor) 组成。在与蓝牙设备通信时,主要就是通过读写 Characteristic 的 value 完成。 每个 Characteristic 由一个 UUID 唯一标识。
  • 描述符 (Descriptor): Descriptor 是描述特征值的已定义属性。例如,Descriptor 可指定人类可读的描述、特征值的取值范围或特定于特征值的度量单位。每个 Descriptor 由一个 UUID 唯一标识。

如下图所示,我们可以简单地理解为:每个蓝牙设备可能提供多个 Service,每个 Service 可能有多个 Characteristic,我们根据蓝牙设备的协议对对应 Characteristic 的值进行读写即可达到与其通信的目的。

GATT

3. UUID (Universally Unique Identifier)

根据蓝牙 4.2 协议规范(Vol 3, Part B, section 2.5.1 UUID),UUID 是一个 128 位的唯一标识符,用来标识 Service 和 Characteristic 等。

为了减少存储和传输 128 位 UUID 值的负担,蓝牙技术联盟预分配了一批 UUID,这一批 UUID 拥有一个共同部分,被称为 Bluetooth Base UUID,即 00000000-0000-1000-8000-00805F9B34FB。因此,预分配的 UUID 也可以使用 16 位或 32 位表示,其中 16 位 UUID 最为常用。使用 16/32 位的 UUID 可以降低存储和传输的负载。开发者自定义的 UUID 应注意不能与预分配的 UUID 冲突。

在微信小程序中,wx.startBluetoothDevicesDiscovery 和 wx.getConnectedBluetoothDevices 的参数支持 16/32/128 位 UUID。在其他接口的参数中,

  • iOS 支持直接使用 16 位 和 128 位的 UUID;
  • Android 8.0.9 版本开始,支持直接使用 16/32/128 位 UUID;
  • Android 8.0.9 以下版本,只支持 128 位的 UUID,需要开发者手动补位到 128 位。补位方式如下
    128位UUID = 16位UUID * 2^96 + Bluetooth Base UUID
    128位UUID = 32位UUID * 2^96 + Bluetooth Base UUID
    
    例如
    0x180F -> 0000180F-0000-1000-8000-00805F9B34FB
    

所有接口的返回值统一为 128 位 UUID。

4. 中心设备的使用流程

4.1 初始化蓝牙模块

在使用蓝牙接口前,必须首先调用 wx.openBluetoothAdapter 初始化蓝牙适配器模块,其他接口必须在初始化后成功方可调用。

当蓝牙开关未开启或手机不支持蓝牙时,会返回错误 (errCode=10001)。此时微信小程序蓝牙模块已经初始化完成,可通过 wx.onBluetoothAdapterStateChange 监听手机蓝牙状态的改变,也可以调用蓝牙模块的所有API。开发者在开发中应该考虑兼容用户在使用微信小程序过程中打开/关闭蓝牙开关的情况,并给出必要的提示,提高可用性。

4.2 扫描并发现蓝牙外围设备

蓝牙模块初始化成功后,一般需要通过 wx.startBluetoothDevicesDiscovery 扫描外围设备。当蓝牙外围设备被扫描到时,会回调 wx.onBluetoothDeviceFound 事件,返回扫描到的设备。扫描设备比较耗费系统资源,请在搜索到需要的设备后及时调用 wx.stopBluetoothDevicesDiscovery 停止搜索。

若之前已连接过某个设备,获取到了 deviceId,可跳过扫描步骤。

// 监听扫描到新设备事件
wx.onBluetoothDeviceFound((res) => {
  res.devices.forEach((device) => {
    // 这里可以做一些过滤
    console.log('Device Found', device)
  })
  // 找到要搜索的设备后,及时停止扫描
  wx.stopBluetoothDevicesDiscovery()
})

// 初始化蓝牙模块
wx.openBluetoothAdapter({
  mode: 'central',
  success: (res) => {
    // 开始搜索附近的蓝牙外围设备
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: false,
    })
  },
  fail: (res) => {
    if (res.errCode !== 10001) return
    wx.onBluetoothAdapterStateChange((res) => {
      if (!res.available) return
      // 开始搜寻附近的蓝牙外围设备
      wx.startBluetoothDevicesDiscovery({
        allowDuplicatesKey: false,
      })
    })
  }
})

4.3 连接设备

蓝牙低功耗设备间要进行通信,必须首先建立连接。

wx.createBLEConnection({
  deviceId, // 搜索到设备的 deviceId
  success: () => {
    // 连接成功,获取服务
    wx.getBLEDeviceServices({
      deviceId,
    })
  }
})

4.4 获取蓝牙外围设备的服务

wx.getBLEDeviceServices({
  deviceId, // 搜索到设备的 deviceId
  success: (res) => {
    for (let i = 0; i < res.services.length; i++) {
      if (res.services[i].isPrimary) {
        // 可根据具体业务需要,选择一个主服务进行通信
      }
    }
  }
})

4.5 读写服务的特征值

wx.getBLEDeviceCharacteristics({
  deviceId, // 搜索到设备的 deviceId
  serviceId, // 上一步中找到的某个服务
  success: (res) => {
    for (let i = 0; i < res.characteristics.length; i++) {
      let item = res.characteristics[i]
      if (item.properties.write) { // 该特征值可写
        // 本示例是向蓝牙设备发送一个 0x00 的 16 进制数据
        // 实际使用时,应根据具体设备协议发送数据
        let buffer = new ArrayBuffer(1)
        let dataView = new DataView(buffer)
        dataView.setUint8(0, 0)
        wx.writeBLECharacteristicValue({
          deviceId,
          serviceId,
          characteristicId: item.uuid,
          value: buffer,
        })
      }
      if (item.properties.read) { // 该特征值可读
        wx.readBLECharacteristicValue({
          deviceId,
          serviceId,
          characteristicId: item.uuid,
        })
      }
      if (item.properties.notify || item.properties.indicate) {
        // 必须先启用 wx.notifyBLECharacteristicValueChange 才能监听到设备 onBLECharacteristicValueChange 事件
        wx.notifyBLECharacteristicValueChange({
          deviceId,
          serviceId,
          characteristicId: item.uuid,
          state: true,
        })
      }
    }
  }
})
// 操作之前先监听,保证第一时间获取数据
wx.onBLECharacteristicValueChange((result) => {
  // 使用完成后在合适的时机断开连接和关闭蓝牙适配器
  wx.closeBLEConnection({
    deviceId,
  })
  wx.closeBluetoothAdapter({})
})

4.6 断开连接和关闭蓝牙适配器

使用完成后,应该在合适的时机断开连接,并关闭蓝牙适配器。

5. 注意事项

  • 在 iOS 上,对特征值的 readwritenotify 操作,由于系统需要获取特征值实例,传入的 serviceIdcharacteristicId 必须由 wx.getBLEDeviceServices 与 wx.getBLEDeviceCharacteristics 中获取到后才能使用。建议统一在建立连接后先执行 wx.getBLEDeviceServices 与 wx.getBLEDeviceCharacteristics 后再进行与蓝牙设备的数据交互。
  • 考虑到蓝牙功能可以间接进行定位,安卓 6.0 及以上版本,无定位权限或定位开关未打开时,无法进行设备搜索。
  • 在安卓上,部分机型获取设备服务时会多出 0000180000001801 UUID 的服务,这是系统行为,注意不要使用这两个服务。
  • 建立连接和关闭连接必须要成对调用。如果未能及时关闭连接释放资源,安卓上容易导致 state 133 GATT ERROR 的异常。
  • 在与蓝牙设备传输数据时,需要注意 MTU(最大传输单元)。如果数据量超过 MTU 会导致错误,建议根据蓝牙设备协议进行分片传输。安卓设备可以调用 wx.setBLEMTU 进行 MTU 协商。在 MTU 未知的情况下,建议使用 20 字节为单位传输。

蓝牙低功耗网状网络(BLE Mesh)

蓝牙低功耗网状网络(BLE Mesh)是建立在蓝牙低功耗(BLE)协议基础上的一种通信协议,它允许大量 BLE 设备组成一个网状网络,在足够大的物理覆盖范围内实现设备之间的互联与协同控制,从而满足多设备场景下的通信需求。

BLE Mesh 通信协议支持低功耗、可扩展性、灵活性、高可靠性、安全性等优秀特性,在智能家居、智能照明、工业自动化、医疗健康、环境监测等领域具有广泛的应用价值。

1. 基础概念

BLE Mesh 网络

BLE Mesh 网络是一种多对多的网络拓扑结构,网络中的设备节点通过「发布 / 订阅机制」收发消息。

设备配网

未配网 BLE Mesh 设备需要完成配网操作后,才能加入 BLE Mesh 网络并成为设备节点,与网络中的其他节点进行消息通信。帮助 BLE Mesh 设备完成配网操作的设备叫做「启动配置设备」。

设备节点

未配网 BLE Mesh 设备经过配网操作后,就成为了 BLE Mesh 网络中的设备节点。设备节点一般都具有中继、代理、好友、低功耗等特性中的一个或多个。

设备节点由多个元素构成,每个元素包含了多个模型,而每个模型定义了节点的基本功能,比如节点所需要的状态、控制状态的消息以及处理消息所产生的动作等。节点功能的实现是基于模型的,模型可分为 SIG 模型和自定义模型,前者由 SIG 定义,而后者由开发者定义。模型也可基于消息的发送 / 接收方分为客户端模型与服务端模型。

Mesh 地址

BLE Mesh 网络中的设备节点之间想要进行消息通信,就需要为每个节点分配地址用于消息的收发。Mesh 地址主要分为单播地址、组播地址、虚拟地址三种。

单播地址是在设备配网成功后由「启动配置设备」分配的。单播地址可能会出现在消息的来源 / 目标地址字段中。发送到单播地址的消息只能由拥有该单播地址的元素进行处理。

组播地址是 BLE Mesh 网络中的一种多播地址,通常用于将设备节点进行分组。如果发送带有组播地址的消息,所有订阅过该组播地址的设备节点都会收到该消息。

虚拟地址与特定的 UUID 标签相关联,可以用作模型的发布地址或订阅地址。

Mesh 消息

Mesh 消息分为控制消息与接入消息。控制消息是与 BLE Mesh 网络操作有关的消息,例如心跳和好友的请求消息。接入消息允许客户端模型检索或设置服务端模型中的状态值,或被服务端用于报告状态值。

Mesh 消息是 BLE Mesh 网络中数据传输的基本单位,由操作码(opcode)和携带参数(parameters)组成,前者用于标识消息的用途唯一性,后者可以存储有效数据,例如目标地址、设备状态等。

代理设备

如果想要不是 BLE Mesh 设备的其他设备(例如手机)也能成为 BLE Mesh 网络中的一员,可以通过与代理设备节点进行 GATT 连接,借助代理设备实现在 BLE Mesh 网络中收发各种消息。

2.「微信小程序 BLE Mesh 插件」使用流程

在微信小程序中,基于标准 BLE Mesh 通信协议,以微信小程序插件形式提供了 BLE Mesh 的基础能力。开发者可以通过「微信小程序 BLE Mesh 插件」实现 BLE Mesh 设备的本地快速配网、控制管理、网络共享等功能。平台提供了「接口文档」与「示例微信小程序」,方便开发者接入使用。

2.1 接入插件

在使用插件前,首先需要在微信小程序管理后台的「设置 – 第三方服务 – 插件管理」中添加插件,开发者可以登录微信小程序管理后台,通过 appid – wx013447465d3aa024 查找插件并添加。然后在 app.json 文件中声明指定版本的插件。关于微信小程序插件的具体介绍可参考「使用插件」。

目前只有申请了「工具—设备管理」服务类目的微信小程序才能使用「微信小程序 BLE Mesh 插件」。

"plugins": {
  "ble-mesh-plugin": {
    "version": "latest",
    "provider": "wx013447465d3aa024"
  }
}

通过 requirePlugin 方法才能获取「微信小程序 BLE Mesh 插件」的相关接口。例如可以像下面这样调用:

const { getMeshBLEManager } = requirePlugin('ble-mesh-plugin')

2.2 初始化 BLE Mesh 蓝牙配置器

在使用微信小程序 BLE Mesh 相关能力前,需要初始化 BLE Mesh 蓝牙配置器,用于扫描发现周围的 BLE Mesh 设备。

const meshBLEManager = getMeshBLEManager()

meshBLEManager.init().then(({ enabled }) => {
  if (!enabled) {
    wx.showModal({
      title: '错误',
      content: '未启用蓝牙功能, 请打开蓝牙后重试',
      showCancel: false,
    })
  }
})

2.3 扫描发现 BLE Mesh 设备

BLE Mesh 蓝牙配置器初始化后,需要通过 meshBLEManager.startScanMeshDevice 扫描 BLE Mesh 设备,如果在附近扫描到设备就会回调 meshBLEManager.onMeshDeviceFound 事件,返回扫描到的 BLE Mesh 设备实例。由于扫描设备操作比较耗费系统资源,请在搜索到需要的设备后及时调用 meshBLEManager.stopScanMeshDevice 停止扫描。

meshBLEManager.onMeshDeviceFound((res) => {
  // 扫描到的 BLE Mesh 设备
  console.log(res.device)
  // 找到需要的设备后,停止扫描操作
  meshBLEManager.stopScanMeshDevice()
})

// 开始扫描 BLE Mesh 设备
meshBLEManager.startScanMeshDevice({
  allowDuplicatesKey: false,
})

2.4 创建 BLE Mesh 网络

想要实现多个 BLE Mesh 设备之间的互联与协同控制,就需要先创建一个 BLE Mesh 网络。

createMeshNetwork({ name: 'mesh_network' }).then((res) => {
  // 创建 BLE Mesh 网络后会生成唯一的网络标识id,用于后续的网络管理、设备配网、设备消息通信等功能。
  console.log(res.networkId)
})

2.5 共享 BLE Mesh 网络

开发者可以通过 exportMeshNetworksimportMeshNetworks 实现 BLE Mesh 网络数据的导入导出,让多个微信小程序用户可以控制管理同一网络下的 BLE Mesh 设备。此外调用 getMeshNetworks 还可以获取当前存在的所有 BLE Mesh 网络列表。

// 导出 BLE Mesh 网络数据
const { restoreData } = exportMeshNetworks({ data: [{ name: 'mesh_network' }] })
// 导入 BLE Mesh 网络数据
importMeshNetworks({ restoreData })
// 获取当前存在的 BLE Mesh 网络列表
const networks = getMeshNetworks() // [{ name: 'network_name', networkId: 'network_id' }]

注意

在通过 exportMeshNetworks 导出 BLE Mesh 网络数据后,可能需要对数据进行持久化存储。为了保证网络安全,开发者应该将数据加密后再执行存储操作,然后在导入时将数据解密。

在通过 importMeshNetworks 将 BLE Mesh 网络数据导入新用户微信小程序时,由于 iOS 系统限制,同一台 BLE Mesh 设备,不同用户获取到的蓝牙 deviceId 不同,导致无法建立代理设备连接。此时需要设备端在配网成功后持续广播 Node Identity 蓝牙广播包,方便微信小程序插件识别设备节点,更新蓝牙 deviceId 。

2.6 BLE Mesh 网络管理

通过 getMeshNetworkManager 可以获取 BLE Mesh 网络管理配置器,它包括了创建 / 删除 BLE Mesh 群组、获取 BLE Mesh 网络中所有节点的单播地址列表以及组播地址列表等功能。

// 获取 BLE Mesh 网络管理配置器
const meshNetworkManager = getMeshNetworkManager({ networkId: 'network_id' })
// 创建 BLE Mesh 群组
const group = meshNetworkManager.createGroup({ name: 'group_name' })
// 删除 BLE Mesh 群组
meshNetworkManager.removeGroup({ name: 'group_name' })
// 获取组播地址列表
const groups = meshNetworkManager.getGroups()
[{
  name, // BLE Mesh 群组名称
  address, // BLE Mesh 组播地址
  nodes, // BLE Mesh 组播地址下绑定的设备节点信息
}]
// 获取单播地址列表
const unicasts = meshNetworkManager.getUnicasts()
[{
  deviceId, // BLE Mesh 设备id
  name, // BLE Mesh 设备名称
  localName, // BLE Mesh 设备广播数据段中的 LocalName 数据段
  address, // BLE Mesh 设备单播地址
}]

2.7 BLE Mesh 设备配网

想要实现 BLE Mesh 设备配网,首先需要获取 BLE Mesh 设备入网配置器 provisioningManager ,然后通过 provisioningManager.provision 完成配网操作。此外还可以通过 provisioningManager.batchProvision 实现一键配网多个 BLE Mesh 设备。当 BLE Mesh 设备完成配网操作后,才算真正加入了 BLE Mesh 网络。

// 获取 BLE Mesh 设备入网配置器
const provisioningManager = getProvisioningManager({ networkId: 'network_id' })
// 单个 BLE Mesh 设备配网
await provisioningManager.provision({
  unprovisionedDevice, // 未配网的 BLE Mesh 设备实例
  authenticationMethod: AuthenticationMethod.NoOOB, // 配网时的 OOB 安全认证方式
})
// 多个 BLE Mesh 设备批量配网
await provisioningManager.batchProvision({
  unprovisionedDevices, // 未配网的 BLE Mesh 设备实例数组
})

2.8 BLE Mesh 设备消息通信

在完成 BLE Mesh 设备配网后,如果想要和设备进行消息通信,实现控制设备与获取设备信息等功能。首先应该获取 BLE Mesh 代理设备客户端配置器 proxyClientManager ,在开启蓝牙扫描的情况下使用 proxyClientManager.hasProxyServer 确认周围是否存在可用的代理设备,然后通过 proxyClientManager.addAppKeyToNodeproxyClientManager.bindAppKeyToModel 将 BLE Mesh 网络中的 AppKey 绑定到目标设备的 Server 模型上,最后发送标准的 BLE Mesh 消息,用于改变目标设备 Server 模型上的状态或者检索相关信息。

// 获取 BLE Mesh 代理设备客户端配置器
const proxyClientManager = getProxyClientManager({ networkId: 'network_id' })
// 检查周围是否存在可用的代理设备 Server
const hasProxyServer = proxyClientManager.hasProxyServer
if (hasProxyServer) {
  // 添加 AppKey 到目标设备
  await this.proxyClientManager.addAppKeyToNode({
    destination, // 目标设备的单播地址
  })
  // 绑定 AppKey 到目标设备的 GenericOnOffServer 模型上
  await proxyClientManager.bindAppKeyToModel({
    destination, // 目标设备的单播地址
    modelId: ModelIds.GenericOnOffServer, // 标准 GenericOnOffServer 模型的 modelId
  })
  // 获取目标设备的 GenericOnOffServer 模型上的开关状态
  const resGet = await proxyClientManager.getOnOffStatus({
    destination, // 目标设备的单播地址或组播地址
  })
  console.log(resGet.source, resGet.message.isOn)
  // 控制目标设备的 GenericOnOffServer 模型上的开关状态
  const resSet = await proxyClientManager.setOnOffStatus({
    destination, // 目标设备的单播地址或组播地址
    status, // 需要设置的开关状态
  })
  console.log(resSet.source, resSet.message.isOn)
  // 开发者还可以通过自定义 BLE Mesh 消息,发送接收最基础的 opcode 和 parameters ,来实现例如 Vendor Model 的功能。
  proxyClientManager.onMessage(({ source, opcode, parameters }) => {
    // handle mesh message
  })
  proxyClientManager.send({
    destination, // 目标设备的单播地址或组播地址
    opcode, // 操作码
    parameters, // 携带参数
  })
}

3. 注意事项

  1. 开发者可以通过「微信小程序 BLE Mesh 插件」示例微信小程序 ,快速接入微信小程序 BLE Mesh 能力。

  2. 关于微信小程序 BLE Mesh 能力的详细描述,请查阅「微信小程序 BLE Mesh 插件」接口文档

  3. 请尽量使用「微信小程序 BLE Mesh 插件」latest 版本,以保证功能完善、稳定可用。

  4. 目前「微信小程序 BLE Mesh 插件」只提供了 BLE Mesh 的基础能力,后面会根据开发者需要持续迭代更新。

蓝牙信标 (Beacon)

基础库 1.2.0 开始支持。

蓝牙信标 (Beacon) 是建立在蓝牙低功耗 (BLE) 协议基础上的一种广播协议。

Beacon 设备作为蓝牙低功耗协议中的外围设备,持续向周围广播包含设备标识的特定数据包,但不能和中心设备建立连接。微信小程序运行的设备作为中心设备,可以收到 Beacon 设备的广播包,实现数据交互。常用于室内定位、消息推送等场景。

微信小程序中,开发者可以通过 wx.startBeaconDiscovery 开始搜索 Beacon 设备,并通过 wx.onBeaconUpdate 接收设备更新事件。

1. 设备标识

每个 Beacon 设备的广播包中,至少携带了以下信息,共同组成了设备的唯一标识符。

  • UUID (16 字节):128 位的 UUID,用于唯一标识微信小程序所识别的一系列信标设备。
  • major (2 字节):0 – 65535 的无符号整数,可以用来区分相同 UUID 的一组设备。
  • minor (2 字节):0 – 65535 的无符号整数,可以用来区分有相同 UUID 和 major 的设备。

2. 设备状态

当微信小程序接收到 Beacon 设备的信号时,还会提供下列信息

  • rssi: 信号强度,单位为 dBm。
  • proximity: Beacon 标识设备距离的枚举值(仅 iOS)。
  • accuracy: Beacon 设备的距离,单位为米。

3. 注意事项

  • Beacon 相关接口可以直接使用,不需要使用 wx.openBluetoothAdapter 初始化蓝牙适配器模块
  • 由于 Beacon 可以被用来进行定位,因此需要微信有系统的位置权限时才能使用。