支付宝小程序:开放平台-官方文档地址:https://docs.alipay.com/mini/api/bluetooth-api#a-namegfgkonamyopenbluetoothadapter
微信小程序:公众平台-官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/api/wx.closeBluetoothAdapter.html
支付宝小程序
介绍
依次用到了支付宝小程序提供的这几个接口:(已知服务id和特征id的情况)
- 初始化蓝牙模块:
my.openBluetoothAdapter。可在页面加载的时候调用 - 关闭蓝牙模块:
my.closeBluetoothAdapter。可在初始化失败(可能蓝牙未打开)的时候调用 - 开始搜寻附近的蓝牙外围设备:
my.startBluetoothDevicesDiscovery。初始化完成或点击事件里调用,搜寻到设备或超时时记得停止搜寻 - 停止搜寻附近的蓝牙外围设备:
my.stopBluetoothDevicesDiscovery。搜索到设备或请求超时时调用 - 监听搜索到新蓝牙设备时事件:
my.onBluetoothDeviceFound。搜索到时记得移除事件监听 - 移除寻找到新的蓝牙设备事件的监听:
my.offBluetoothDeviceFound。搜索到设备时调用 - 连接蓝牙设备:
my.connectBLEDevice。放在监听事件的回调函数里 - 断开连接:
my.disconnectBLEDevice。特定事件调用 - 向蓝牙设备特征值中写入数据:
my.writeBLECharacteristicValue。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用 - 读取蓝牙设备特征值中的数据:
my.readBLECharacteristicValue。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用
在不清楚服务id和特征id值的情况、或在调试阶段,可使用的接口:获取蓝牙设备所有 service(服务) my.getBLEDeviceServices、获取蓝牙设备所有 characteristic(特征值) my.getBLEDeviceCharacteristics。记住这个顺序:用macId或蓝牙名去匹配蓝牙,在蓝牙连接成功时会获得deviceId,用deviceId去获取想要的serverId,用deviceId和serverId去获取想要的characteristicId,再用这三个id去读/写数据。
代码示例
此示例中的服务id和特征值id为固定值,所以没有去主动获取。如果需要获取可在连接成功时调用相应接口
axml文件:
button type="default" size="defaultSize" onTap="searchBluetooth" 搜索蓝牙设备 /buttonbutton type="default" size="defaultSize" onTap="disconnectBLEDevice" 断开连接 /buttonbutton type="default" size="defaultSize" onTap="writeBluetoothData1" 执行1操作 /buttonbutton type="default" size="defaultSize" onTap="writeBluetoothData2" 执行2操作 /buttonjs文件:
Page({ data: { deviceId: "", //设备id serviceId: "abc0", //固定的服务id characteristicId: "abc1", //固定的特征值id-1 randomCharacteristicId: "FFF2" //固定的特征值id-2 }, onLoad() { var that = this; my.openBluetoothAdapter({ //初始化蓝牙模块 success: (res) = { that.searchBluetooth(); //开始搜索蓝牙设备 }, fail:(res) = { console.log("------初始化蓝牙模块失败!!------"); my.alert({ content: "请开启手机蓝牙后再试!" }); } }); }, //移除事件监听 onUnload() { my.offBluetoothDeviceFound(this.callback); }, searchBluetooth: function(){ //开始搜索蓝牙设备 var that = this; my.startBluetoothDevicesDiscovery({ services: [], success: (res) = { my.showLoading({ content: '正在搜索蓝牙设备' }); //搜索到蓝牙事件监听 that.callback = that.callback.bind(that); my.onBluetoothDeviceFound(that.callback); //5s内未搜索到设备,关闭搜索,关闭蓝牙模块 setTimeout(function(){ if (!that.data.deviceId){ my.hideLoading(); my.showToast({ type: 'exception', content: '搜索设备超时', duration: 3000 }); console.log("搜索设备超时"); my.stopBluetoothDevicesDiscovery({}); //关闭搜索 my.offBluetoothDeviceFound(that.callback); //移除搜索设备监听 my.closeBluetoothAdapter({}); //关闭蓝牙模块 } }, 5000); }, fail:(res) = { console.log("-------调用搜寻蓝牙设备失败--------"); } }); }, callback(res) { //新搜索到设备的回调函数(通过蓝牙名去匹配) var deviceObj = res.devices[0]; //{"deviceId": "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "RSSI": -83, "manufacturerData": "", "deviceName": "ABCDEFG", "advertisData":"", "localName": "ABCDEFG", "name": "ABCDEFG"} var name = deviceObj.name || deviceObj.deviceName; if(name && name === "13579"){ //搜索到的目标蓝牙设备信息 my.stopBluetoothDevicesDiscovery({}); //关闭搜索 my.offBluetoothDeviceFound(this.callback); //移除搜索设备监听 this.setData({ deviceId: deviceObj.deviceId }); //存储目标蓝牙设备id this.connectBLEDevice(); //去连接蓝牙设备 } }, connectBLEDevice: function(){ //连接低功耗蓝牙设备 var that = this; var deviceId = that.data.deviceId; my.connectBLEDevice({ deviceId: that.data.deviceId, success: (res) = { console.log("蓝牙连接成功"); my.hideLoading(); }, fail:(res) = {} }); }, disconnectBLEDevice: function(){ //断开与低功耗蓝牙设备的连接 var that = this; my.disconnectBLEDevice({ deviceId: that.data.deviceId, success: (res) = { console.log("已断开连接!!"); }, fail:(res) = {} }); }, writeBluetoothData1: function(){ //写入执行1指令 var that = this; my.writeBLECharacteristicValue({ deviceId: that.data.deviceId, serviceId: that.data.serviceId, characteristicId: that.data.characteristicId, value: "123456789" }); }, writeBluetoothData2: function(){ //写入执行2指令 var that = this; my.writeBLECharacteristicValue({ deviceId: that.data.deviceId, serviceId: that.data.serviceId, characteristicId: that.data.characteristicId, value: "987654321" }); }});微信小程序
介绍
用法与支付宝小程序基本相同,几点不同如下:
- 没有 移除寻找到新的蓝牙设备事件的监听 方法;
- 连接蓝牙设备后返回的服务id和特性值id与支付宝的不同,是一个很长的字符串(我这里先去获取了服务id和特性值id,然后将它们做了个存储,方便后续使用);
- 读取蓝牙设备特征值中的数据 接口,返回的是一个二进制数据。使用的时候需做下处理,且要在wx.onBLECharacteristicValueChange方法回调中接收数据;
- 向蓝牙设备特征值中写入数据 接口,需写入二进制数据。需转换数据格式后再写入。
依次用到了微信小程序提供的这几个接口:
- 初始化蓝牙模块:
wx.openBluetoothAdapter。可在页面加载的时候调用; - 关闭蓝牙模块:
wx.closeBluetoothAdapter; - 开始搜寻附近的蓝牙外围设备:
wx.startBluetoothDevicesDiscovery。初始化完成或点击事件里调用,搜索并连接到设备后记得停止搜寻; - 停止搜寻附近的蓝牙外围设备:
wx.stopBluetoothDevicesDiscovery。已经找到需要的蓝牙设备并不需要继续搜索时调用; - 监听寻找到新设备的事件:
wx.onBluetoothDeviceFound; - 连接蓝牙设备:
wx.createBLEConnection; - 断开连接:
wx.closeBLEConnection; - 获取蓝牙设备所有服务(service):
wx.getBLEDeviceServices; - 获取蓝牙设备某个服务中所有特征值(characteristic):
wx.getBLEDeviceCharacteristics; - 向蓝牙设备特征值中写入二进制数据:
wx.writeBLECharacteristicValue。搜寻到指定设备,获取到(或有指定的)serverId 和 characteristicId 时调用 - 读取蓝牙设备特征值中的二进制数据值:
wx.readBLECharacteristicValue。读取到的信息需要在 onBLECharacteristicValueChange 方法注册的回调中获取。
代码示例
axml文件:
button type="default" size="defaultSize" bindtap="startBluetoothDevicesDiscovery" 搜索蓝牙设备 /buttonbutton type="default" size="defaultSize" bindtap="closeBLEConnection" 断开连接 /buttonbutton type="default" size="defaultSize" bindtap="writeBluetoothData1" 执行1操作 /buttonbutton type="default" size="defaultSize" bindtap="writeBluetoothData2" 执行2操作 /buttonjs文件:
Page({ data: { deviceId: "" //设备id }, onLoad() { var that = this; wx.openBluetoothAdapter({ //初始化蓝牙模块 success: (res) = { that.startBluetoothDevicesDiscovery(); //开始搜索蓝牙设备 }, fail: (res) = { console.log("------初始化蓝牙模块失败!!------"); wx.showLoading({ title: '请打开蓝牙', icon: 'loading', duration: 3000 }) } }); }, //当退出页面,断开蓝牙连接 onUnload() { wx.closeBLEConnection({ deviceId: this.data.deviceId, success(res) { } }) }, startBluetoothDevicesDiscovery: function(){ //开始搜索蓝牙设备 var that = this; wx.startBluetoothDevicesDiscovery({ allowDuplicatesKey: true, services: [], success: (res) = { //搜索到新的蓝牙设备时触发事件 that.callback = that.callback.bind(that); wx.onBluetoothDeviceFound(that.callback); //5s内未搜索到设备,关闭搜索,关闭蓝牙模块 setTimeout(function () { if (!that.data.deviceId) { that.setData({ hiddenLoading: true }); wx.showToast({title: '搜索设备超时',duration: 3000 }) console.log("搜索设备超时"); wx.stopBluetoothDevicesDiscovery({}); //关闭搜索 wx.closeBluetoothAdapter({}); //关闭蓝牙模块 } }, 5000); }, fail: (res) = { } }); }, callback(res) { //新搜索到设备的回调函数(通过mac地址去匹配) var deviceObj = res.devices[0]; if (this.data.mac.toLowerCase() === deviceObj.manufacturerData.toLowerCase()) { wx.stopBluetoothDevicesDiscovery({}); //关闭搜索 this.setData({ deviceId: deviceObj.deviceId }); //存储目标蓝牙设备id this.connectBLEDevice(); //去连接蓝牙设备 } }, connectBLEDevice: function(){ //连接低功耗蓝牙设备 var that = this; var deviceId = that.data.deviceId; wx.createBLEConnection({ deviceId: that.data.deviceId, success: (res) = { //连接蓝牙设备成功 wx.getBLEDeviceServices({ deviceId: that.data.deviceId, success(res) { //获取服务id成功 that.setData({ serviceId: res.services[1].uuid}); wx.getBLEDeviceCharacteristics({ deviceId: that.data.deviceId, serviceId: that.data.serviceId, success(res) { //获取特性值id成功 that.setData({ characteristicId: res.characteristics[0].uuid }); that.setData({ randomCharacteristicId: res.characteristics[1].uuid }); wx.onBLECharacteristicValueChange(function (res) { //读取数据成功回调-接收并存储转换后的数据 that.setData({ charact1: that.ab2hex(res.value) }); }); wx.readBLECharacteristicValue({ //读取二进制数据 deviceId: that.data.deviceId, serviceId: that.data.serviceId, characteristicId: that.data.randomCharacteristicId, success: (res) = { } }); } }) } }) }, fail: (res) = { console.log("连接蓝牙设备失败"); console.log(res); } }); }, ab2hex: function(buffer) { //将二进制数组进行转换 var hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return ('00' + bit.toString(16)).slice(-2) } ) return hexArr.join(''); }, closeBLEConnection: function(){ //断开与低功耗蓝牙设备的连接 var that = this; wx.closeBLEConnection({ deviceId: that.data.deviceId, success: (res) = { console.log("已断开连接!!"); } }); }, writeBluetoothData1: function(){ //写入执行1指令 var that = this; wx.writeBLECharacteristicValue({ deviceId: that.data.deviceId, serviceId: that.data.serviceId, characteristicId: that.data.characteristicId, value: that.getBinaryData("0B0075") }); }, writeBluetoothData2: function(){ //写入执行2指令 var that = this; wx.writeBLECharacteristicValue({ deviceId: that.data.deviceId, serviceId: that.data.serviceId, characteristicId: that.data.characteristicId, value: that.getBinaryData("75000B") }); }, getBinaryData: function (message) { //将数据转为二进制数组 let buffer = new ArrayBuffer(6); let dataView = new DataView(buffer); var numTitle = 0; for (var i = 0; i message.length; i = i + 2) { var numStr16 = message.substr(i, 2); var num = parseInt(numStr16, 16); dataView.setUint8(numTitle, num); numTitle++; } return buffer; }});最后
匹配蓝牙设备的时候,可以通过设备名,但是如果附近有多个同名的设备时,就需要通过mac地址来匹配对应的蓝牙设备了。而在苹果手机上返回的mac地址是经过处理后不准确的。如果有这种情况可以联系蓝牙设备硬件方,将mac地址存入manufacturerData中,通过它的值去匹配&连接蓝牙。













