蓝牙项目-微信小程序蓝牙使用分享
导语
蓝牙在日常生活中广泛使用的一项技术,小程序给了我们前端工程师一个控制蓝牙的方法,带上你的设备,来看看怎么控制你的蓝牙设备吧。
1. 小程序蓝牙介绍 蓝牙终端:我们常说的硬件设备,包括手机,电脑等等。 设备地址:每个蓝牙设备都有一个设备地址deviceId,但是安卓和IOS差别很大,安卓下设备地址就是mac地址,但是IOS无法获取mac地址,所以设备地址是针对本机范围有效的UUID,所以这里需要注意,后面会介绍。
2. API总览
小程序对蓝牙设备的操作有18个API API名称说明 openBluetoothAdapter初始化蓝牙适配器,在此可用判断蓝牙是否可用 closeBluetoothAdapter关闭蓝牙连接,释放资源 getBluetoothAdapterState获取蓝牙适配器状态,如果蓝牙未开或不可用,这里可用检测到 onBluetoothAdapterStateChange蓝牙适配器状态发生变化事件,这里可用监控蓝牙的关闭和打开动作 startBluetoothDevicesDiscovery开始搜索设备,蓝牙初始化成功后就可以搜索设备 stopBluetoothDevicesDiscovery当找到目标设备以后需要停止搜索,因为搜索设备是比较消耗资源的操作 getBluetoothDevices获取已经搜索到的设备列表 onBluetoothDeviceFound当搜索到一个设备时的事件,在此可用过滤目标设备 getConnectedBluetoothDevices获取已连接的设备 createBLEConnection创建BLE连接 closeBLEConnection关闭BLE连接 getBLEDeviceServices获取设备的服务列表,每个蓝牙设备都有一些服务 getBLEDeviceCharacteristics获取蓝牙设备某个服务的特征值列表 readBLECharacteristicValue读取低功耗蓝牙设备的特征值的二进制数据值 writeBLECharacteristicValue向蓝牙设备写入数据 notifyBLECharacteristicValueChange开启蓝牙设备notify提醒功能,只有开启这个功能才能接受到蓝牙推送的数据 onBLEConnectionStateChange监听蓝牙设备错误事件,包括异常断开等等 onBLECharacteristicValueChange监听蓝牙推送的数据,也就是notify数据
4,小程序蓝牙的主要流程 1,开启蓝牙:调用openBluetoothAdapter,来判断用户手机的是否支持蓝牙使用 wx.openBluetoothAdapter({
success: function (res) { conosle.log('该用户支持蓝牙的使用') wx.getBluetoothAdapterState()调用小程序蓝牙检测是否开启 }, fail(res){ conosle.log('该用户不支持蓝牙的使用')
} }) 2,
检查蓝牙状态:调用getBluetoothAdapterState来检查蓝牙是否开启,如果没有开启可以在这里提醒用户开启蓝牙,并且能在开启后自动启动下面的步骤
这里有一个坑:IOS里面蓝牙状态变化以后不能马上开始搜索,否则会搜索不到设备,必须要等待2秒以上。
wx.getBluetoothAdapterState({ //获取本机蓝牙适配器状态 判断用户是否开启蓝牙 success: res => { console.log('蓝牙状态', res) //discovering 是否正在搜索设备 available 蓝牙适配器是否可用 if (res.available == false) { wx.showToast({ title: '设备无法开启蓝牙连接', icon: 'none' }) } else if (res.discovering == false){ //discovering 是否正在搜索设备 wx.startBluetoothDevicesDiscovery() 调用搜索外围设备 } else if (res.available){ //available 蓝牙适配器是否可用 wx.startBluetoothDevicesDiscovery()
调用搜索外围设备
} } }) 3,开始搜寻附近的蓝牙外围设备
wx.startBluetoothDevicesDiscovery
开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索并连接到设备后调用(
wx.onBluetoothDeviceFound 后结束,下一有介绍改api使用) wx.stopBluetoothDevicesDiscovery 方法停止搜索。
wx.startBluetoothDevicesDiscovery({ //开始搜寻附近的蓝牙外围设备
services: [this.serviceId], //搜索对应设备的id 以微信硬件平台的蓝牙智能灯为例,主服务的 UUID 是 FEE7。传入这个参数,只搜索主服务 UUID 为 FEE7 的设备 allowDuplicatesKey:false,
是否允许重复上报同一设备。如果允许重复上报,则 wx.onBlueToothDeviceFound 方法会多次上报同一设备,但是 RSSI 值会有不同。
success:res =>{ console.log(res); if (!res.isDiscovering) { //是否在搜索到了设备 this.getBluetoothAdapterState() }else{ console.log('1'); // this.getSystemInfo() this.onBluetoothDeviceFound() //设备参数返回成功 就去执行搜索设备 安卓mac 和 ios uuid (作为连接设备人口参数,安卓得不到mac,ios得不到uuid就无法连接设备成功) } }, fail: err => { } })
4,onBluetoothDeviceFound 获取设备的mac和uuid,这里分为两个场景,可以通过wx.getSystemInfo该api来判断是不是安卓或者ios,是安卓手机的话,就获取设备mac地址,是ios的手机的话,就获取uuid(),这里得注意,uuid,设备蓝牙无法识别,要转化成十六进制方法如下:
// ArrayBuffer转16进度字符串示例functionab2hex(buffer){consthexArr =Array.prototype.map.call(newUint8Array(buffer),function(bit){return('00'+ bit.toString(16)).slice(-2) } )returnhexArr.join('')}wx.onBluetoothDeviceFound(function(devices){console.log('new device list has founded')console.dir(devices)console.log(ab2hex(devices[0].advertisData))}) wx.onBluetoothDeviceFound((res) => { const that=this; res.devices.forEach(device => { console.log(device) that.advertisData(写死的mac地址) 我这里是从后台接口获取的,你们做测试的话,可以写死
if (_advertisData == that.advertisData) that.advertisData=_advertisData advertisData 保存在全局变量,因为蓝牙连接的时候需要使用他 wx.setStorageSync('device', device.deviceId)//第一搜索到设备 保存在本地,给下次连接蓝牙的时候使用,下次俩连接相同的蓝牙的时候,就不需要再次去执行这个api-onBluetoothDeviceFound
wx. stopBluetoothDevicesDiscovery() // 设备匹配的化已经搜索到,停止搜索 console.log('设备已经搜索到,停止搜索') wx.createBLEConnection() 这个去执行连接方法 } }) }) 5,wx.createBLEConnection 连接低功耗蓝牙设备。
若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。 连接设备这里,建议大家延迟一下和做递归循环处理,最好是10次左右把,过快连接和一次连接会出现连接失败,安卓手机概率性特别打,在项目中被坑死了,哈哈,现在已经半死不活,跟大家开一个小玩笑,快乐一下。 setTimeout(() => { wx.createBLEConnection({ deviceId: this.deviceId, success: res => { console.log('连接', res) if (res.errCode == 0) { wx.showToast({ title: '蓝牙连接设备成功', icon: 'none' })
连接成功以后就开始查询设备的服务列表:getBLEDeviceServices,然后根据目标服务ID或者标识符来找到指定的服务ID
getBLEDeviceServices(this.deviceId) } }, fail: err => { self.openlock(count++); // console.log('连接失败:', err) }) }, 500) 6,getBLEDeviceServices 获取蓝牙设备所有服务(service)。
这里有个坑的地方:如果是安卓下如果你知道设备的服务ID,你可以省去getBLEDeviceServices的过程,但是IOS下即使你知道了服务ID,也不能省去getBLEDeviceServices的过程,这是小程序里面需要注意的一点。
wx.getBLEDeviceServices({ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId, success(res) { 返回的参数 uuidstring蓝牙设备服务的 uuid isPrimaryboolean该服务是否为主服务 console.log('device services:', res.services) }})
7 ,
获取服务特征值:每个服务都包含了一组特征值用来描述服务的一些属性,比如是否可读,是否可写,是否可以开启notify通知等等,当你跟蓝牙通信时需要这些特征值ID来传递数据。
,wx.getBLEDeviceCharacteristics({ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接deviceId, // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取serviceId, success(res) {console.log('device getBLEDeviceCharacteristics:', res.characteristics) } }) 8,获取特征值ID以后就可以开启notify通知模式,同时开启监听特征值变化消息 wx.notifyBLECharacteristicValueChange({ state: true, deviceId: device_id, serviceId: service_id, characteristicId:notify_id, complete(res) { }, fail(res){ console.log(res); } })
9.writeBLECharacteristicValue 向小程序写人二进制数据 这里面有个坑:开启notify以后并不能马上发送消息,蓝牙设备有个准备的过程,需要在setTimeout中延迟1秒以上才能发送,否则会发送失败 writeBLECharacteristicValue = function (deviceId, serviceId, buffer) { //deviceIdstring是蓝牙设备 id //serviceIdstring是蓝牙特征值对应服务的 uuid //characteristicIdstring是蓝牙特征值的 uuid //valueArrayBuffer是蓝牙设备特征值对应的二进制值 return new Promise((resolve, reject) => { wx.writeBLECharacteristicValue({ deviceId,//设备的 id serviceId, //0000FFF0-0000-1000-8000-00805F9B34FB characteristicId: this.characteristicId,//0000FFF6-0000-1000-8000-00805F9B34FB value: buffer,//蓝牙设备特征值对应的二进制值 success: res => { resolve(res) }, fail: err => { reject(err) } }) }) } 10,最后工作完成 断开小程序蓝牙
断开与低功耗蓝牙设备的连接。
wx.closeBLEConnection({
deviceId: device_id, success(res) { console.log(res) }, fail(res) { console.log(res) } })
关闭蓝牙模块。调用该方法将断开所有已建立的连接并释放系统资源。建议在使用蓝牙流程后,与 wx.openBluetoothAdapter 成对调用。 wx.closeBluetoothAdapter({ success: function (res) { console.log(res) } })
上一篇 下一篇