1、检查小程序是否授权蓝牙功能
initBluetooth() {const that = thiswx.getSetting({success: (res) => {if (res.authSetting.hasOwnProperty('scope.bluetooth')) {//'scope.bluetooth'属性存在,且为falseif (!res.authSetting['scope.bluetooth']) {wx.showModal({title: '温馨提示',showCancel: false,content: '获取蓝牙授权失败,需要手动授权'})} else {that.openBluetooth();}} else {//'scope.bluetooth'属性不存在,需要授权that.openBluetooth();}}})},
wx.getSetting()
方法获取用户的设置信息res.authSetting
包含scope.bluetooth
属性,表示已经获取到了蓝牙权限的设置信息scope.bluetooth
的值为false
,即用户没有授权蓝牙权限,为true
,即用户已经授权蓝牙权限,调用openBluetooth()
方法打开蓝牙功能
打开授权
openBluetooth() {const that = thiswx.closeBluetoothAdapter({success(res) {wx.openBluetoothAdapter({success: function (res) {/*getBluetoothAdapterState() 获取本机蓝牙适配器状态,判断是否可用,available为false则因为用户没有开启系统蓝牙*/wx.getBluetoothAdapterState({success: function (res) {that.setData({findBluetoothState: setInterval(() => {if (!that.data.theBluetoothState) {that.initBluetooth()clearInterval(that.data.findTimer)}wx.getBluetoothAdapterState({success: function (res) {if (!res.available) {...}},fail: function (res) {...}})}, 1000)})// res.available==true适配器可用 res.available==false适配器不可用if (res.available) {that.findBluetooth()} else {wx.showModal({title: '温馨提示',showCancel: false,content: '蓝牙设备不可用',success(res) {...}})}},fail: function (res) {wx.showModal({title: '温馨提示',showCancel: false,content: '蓝牙设备不可用',success(res) {if (res.confirm) {wx.hideLoading()}}})}})},fail: function (err) {console.log(err);wx.showModal({title: '温馨提示',showCancel: false,content: '蓝牙初始化失败,请确认蓝牙功能已开启',success(res) {...}})}})}})},
wx.closeBluetoothAdapter()
方法关闭蓝牙适配器,在成功关闭蓝牙适配器后的回调函数中,调用wx.openBluetoothAdapter()
方法打开蓝牙适配器。先关闭再打开
的方式来初始化蓝牙功能,确保蓝牙适配器工作在一个可靠
的状态下,这种做法可以帮助解决一些潜在的问题,比如之前可能存在的连接问题、缓存状态或其他异常情况wx.getBluetoothAdapterState()
方法获取本机蓝牙适配器的状态- 蓝牙适配器可用(
res.available 为 true
),则去查找蓝牙设备;不可用(res.available 为 false
),则给出提示
2、搜索附近蓝牙设备并匹配
findBluetooth() {const that = thiswx.startBluetoothDevicesDiscovery({services: [],allowDuplicatesKey: false,success: function () {//获取蓝牙设备输出信息列表let aaa = setInterval(() => {wx.getBluetoothDevices({success: function (res) {res.devices.forEach(item => {if (item.advertisData !== '') {if (...) {console.log('匹配到设备:deviceName-' + item.deviceName + ',deviceId-' + item.deviceId);that.creatDevice(item.deviceId)clearInterval(aaa)}}})}})}, 1000)},fail: function (err) {wx.showModal({title: '温馨提示',showCancel: false,content: '搜索蓝牙失败,请检测手机蓝牙,定位功能是否已开启',success(res) {if (res.confirm) {...}}})}});},
wx.startBluetoothDevicesDiscovery()
方法开始搜索附近的蓝牙设备setInterval()
方法每隔一段时间执行一次蓝牙设备搜索操作,在每次执行时,使用wx.getBluetoothDevices()
方法获取附近的蓝牙设备列表,根据匹配的条件,找到对应的设备,拿到设备的deviceId
去与该设备进行连接,注意及时清理定时器
拓展:
wx.getBluetoothDevices()
和 wx.onBluetoothDeviceFound
是小程序中用于搜索蓝牙设备的两种不同方法,它们有以下区别:
1、wx.getBluetoothDevices
- 用来主动搜索附近的蓝牙设备,调用该方法后会返回附近的蓝牙设备列表
- 是一个一次性的操作,即调用一次就会返回当前时刻附近的蓝牙设备列表,之后如果需要重新搜索需要再次调用该方法
- 适用于需要手动触发搜索蓝牙设备的场景,比如用户点击搜索按钮时
2、wx.onBluetoothDeviceFound
- 用来监听附近蓝牙设备的发现事件,当有新的蓝牙设备被发现时会触发该事件,从而可以实时获取附近蓝牙设备的信息
- 是一个被动的操作,即当有新的蓝牙设备被发现时,会触发相应的事件回调函数,无需手动触发搜索
- 适用于需要实时监测附近蓝牙设备变化的场景,比如展示附近蓝牙设备列表并实时更新
3、连接蓝牙设备
creatDevice(deviceId) {const that = thiswx.getConnectedBluetoothDevices({services: [this.data.serviceId],success(res) {console.log(res);if (res.devices.length > 0) {that.getServices(deviceId)} else {wx.createBLEConnection({deviceId,success: function (res) {console.log('连接成功输出信息', res)wx.onBLEConnectionStateChange(function (res) {// 该方法回调中可以用于处理连接意外断开等异常情况console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)if (!res.connected) {console.log('连接断开');wx.offBLEConnectionStateChange()clearTimeout(that.data.doLinkAgainTimer)that.setData({doLinkAgainTimer: setTimeout(() => {that.creatDevice(deviceId)}, 200),})}})that.getServices(deviceId)},fail: function (err) {console.log(err, '连接失败')},})}},fail(err) {console.log(err);}})
},
- 使用
wx.getConnectedBluetoothDevices()
方法获取已连接的蓝牙设备列表 - 如果已连接的设备列表中包含了符合特定服务 UUID 的设备,则直接去获取服务
- 如果未找到已连接的符合条件的设备,则调用
wx.createBLEConnection()
方法尝试连接指定的设备 - 如果连接成功,则会设置一个监听器
wx.onBLEConnectionStateChange()
来监测蓝牙连接状态的变化。如果连接意外断开,会在回调函数中重新尝试连接,并设置一个定时器来控制重新连接的时间间隔。
4、获取服务和特征值
getServices(deviceId) {const that = thiswx.getBLEDeviceServices({// 这里的 deviceId 需要已经通过 wx.createBLEConnection 与对应设备建立连接deviceId,success(res) {console.log('获取服务:', res)that.getServicesCharacteristics(deviceId)},fail(err) {console.log('获取服务失败:', err);}})
},
getServicesCharacteristics(deviceId) {const that = thiswx.getBLEDeviceCharacteristics({// 这里的 deviceId 需要已经通过 wx.createBLEConnection 与对应设备建立连接deviceId,serviceId: this.data.serviceId,success(res) {console.log('获取特征值:', res);let characteristics = res.characteristics.find(item => item.properties.notify)that.startNotice(characteristics.uuid)},fail(err) {console.log('获取特征值失败:', err);}})},
wx.getBLEDeviceServices
获取到服务列表,里面每一条数据代表一个服务,UUID
是用来唯一标识一个蓝牙服务的字符串wx.getBLEDeviceCharacteristics
获取该服务的所有特征值列表,用properties
来区分,代表该特征值支持的操作类型
5、启动蓝牙服务值变化监听及监听特征值变化
startNotice(uuid){var that = this;wx.notifyBLECharacteristicValueChange({state: true, // 启用 notify 功能deviceId: that.data.deviceid,serviceId: that.data.services,characteristicId: uuid, //第一步 开启监听 notityid 第二步发送指令 writesuccess: function (res) {wx.onBLECharacteristicValueChange(function (res) {}})
},
wx.notifyBLECharacteristicValueChang
用于启用蓝牙特征值变化通知wx.onBLECharacteristicValueChange
用于监听蓝牙设备特征值变化,当特征值发生变化时,会触发这个函数,并可以在这里获取变化后的值并进行相应的处理
6、建立长连接
蓝牙设备通常需要建立长连接才能进行稳定的数据传输和控制。默认情况下,微信小程序与蓝牙设备的连接会在一定时间内保持活跃,如果超过一定时间没有数据交互或者没有持续发送心跳包等保持连接的机制,连接可能会自动断开。
获取随机数并进行外部认证通常用于建立安全连接
获取随机数
:设备A生成一个随机数,并将其发送给设备B进行外部认证
:设备B收到随机数后,可能会使用预共享密钥或其他加密算法对随机数进行处理,然后将处理后的结果发送给设备A验证认证结果
:设备A收到处理后的结果后,进行验证以确保通信双方的身份和通信的完整性