微信小程序

您所在的位置:网站首页 蓝牙的配置服务什么意思呀怎么用 微信小程序

微信小程序

2024-07-14 05:10| 来源: 网络整理| 查看: 265

文章目录 前言准备注意事项开发文档概述扩展代码开发关于notify开启成功后,onBLECharacteristicValueChange无法监听的问题

前言

之前BLE蓝牙通信博客中,重点说明了使用读 -- 写的模式,实现手机端和设备端的BLE信息交互操作。

但在一般的BLE设备中,存在可以使用notify通信的方式。

本篇博客重点说明小程序 BLE使用notify实现数据交互的方式,以及部分测试时碰见的坑!

准备

在开始写具体代码之前,需要准备以下材料:

微信小程序开发者工具带有BLE的设备,且某个特征值对象支持notify一款支持BLE的手机 注意事项

android微信支持BLE蓝牙的微信版本为:6.5.7;

ios微信支持BLE蓝牙的微信版本为:6.5.6。

所以做BLE蓝牙开发,为了提高用户的小程序体验感,需要对用户使用的微信版本以及android版本进行判断,并做合理的解决方式。

开发文档概述

在使用BLE的notify功能之前,还需要熟读微信小程序开发文档。特别注意以下几个重要的API:

1、手机蓝牙端接口

关于手机蓝牙端,需要注意以下几个接口:

wx.openBluetoothAdapter 初始化蓝牙适配器 wx.getBluetoothAdapterState 获取本机蓝牙适配器状态 wx.onBluetoothAdapterStateChange 监听蓝牙适配器状态变化事件

其次,在使用这些接口后,需要保证资源释放:

wx.closeBluetoothAdapter(Object object); //释放手机蓝牙端资源

2、扫描周围设备接口

扫描周围蓝牙设备等操作,需要使用到以下几种接口:

wx.startBluetoothDevicesDiscovery 开始搜寻附近的蓝牙外围设备 wx.getBluetoothDevices 获取所有已发现的蓝牙设备 wx.onBluetoothDeviceFound 监听寻找到新设备的事件

当然这些资源使用后,也需要在最后阶段进行释放。

wx.stopBluetoothDevicesDiscovery 停止搜寻附近的蓝牙外围设备

3、连接操作接口 当扫描到指定的设备后,需要执行连接操作,此时需要使用下列接口:

wx.createBLEConnection 连接低功耗蓝牙设备 wx.onBLEConnectionStateChange 监听低功耗蓝牙连接的状态事件

当然连接操作也是一种占用资源的操作,需要在最后进行资源的释放

wx.closeBLEConnection 断开与低功耗蓝牙设备的连接 wx.offBLEConnectionStateChange(function callback) 关闭连接状态变化的监听事件

4、获取服务和特征值对象接口 连接成功后,在android系统中,可以直接进行数据的交互操作,但在ios系统中,直接进行数据交互时,会产生10004 报错。此时则需要保证使用下列代码。在之前博客中也做了详细说明介绍。

wx.getConnectedBluetoothDevices 根据 uuid 获取处于已连接状态的设备 wx.getBLEDeviceServices 获取蓝牙设备所有 service(服务) wx.getBLEDeviceCharacteristics 获取蓝牙设备所有 characteristic(特征值)

5、通信接口 之前博客中重大使用的读-写操作,本篇博客使用notify实现交互,需要使用到下列几种接口:

wx.writeBLECharacteristicValue 向低功耗蓝牙设备特征值中写入二进制数据 wx.notifyBLECharacteristicValueChange 启用低功耗蓝牙设备特征值变化时的 notify 功能 wx.onBLECharacteristicValueChange 监听低功耗蓝牙设备的特征值变化

当然,也需要对监听进行资源释放:

wx.offBLECharacteristicValueChange(function callback) 关闭对特征值数据变化的监听 扩展

由于小程序需要兼容android和ios,所以需要使用到以下几种自定义的api接口:

onLaunch: function() { this.globalData.sysinfo = wx.getSystemInfoSync() }, getModel: function () { //获取手机型号 return this.globalData.sysinfo["model"] }, getVersion: function () { //获取微信版本号 return this.globalData.sysinfo["version"] }, getSystem: function () { //获取操作系统版本 return this.globalData.sysinfo["system"] }, getPlatform: function () { //获取客户端平台 return this.globalData.sysinfo["platform"] }, getSDKVersion: function () { //获取客户端基础库版本 return this.globalData.sysinfo["SDKVersion"] }

对手机微信版本和系统版本做比较,封装有一个版本比较的方法:

versionCompare: function (ver1, ver2) { //版本比较 var version1pre = parseFloat(ver1) var version2pre = parseFloat(ver2) var version1next = parseInt(ver1.replace(version1pre + ".", "")) var version2next = parseInt(ver2.replace(version2pre + ".", "")) if (version1pre > version2pre) return true else if (version1pre version2next) return true else return false } } 代码开发

1、android 6.0 以上的手机未打开系统定位服务时,搜索不到蓝牙设备;

首先需要在app.json中对位置信息进行注册:

"permission": { "scope.userLocation": { "desc": "您的位置信息将用于设备定位和蓝牙操作" } },

其次在代码调用中也需要进行权限校验:

//判断系统版本、微信版本、定位服务等权限和信息 function checkPhoneInfo(obj){ //Android 从微信 6.5.7 开始支持,iOS 从微信 6.5.6 开始支持 //第一项,如果手机是android系统,需要判断版本信息 if (apps.getPlatform() == "android" && versionCompare("6.5.7", apps.getVersion())) { wx.showModal({ title: '提示', content: '当前微信版本过低,请更新至最新版本', showCancel: false }); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); return; } //第二项,如果手机是ios系统,需要判断版本信息 if (apps.getPlatform() == "ios" && versionCompare("6.5.6", apps.getVersion())) { wx.showModal({ title: '提示', content: '当前微信版本过低,请更新至最新版本', showCancel: false }); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); return; } //版本 以及 平台校验完毕后 需要判断蓝牙的相关信息 //微信小程序 android6.0手机需要开启位置服务,否则扫描不到设备 console.log("当前系统版本:" + apps.getSystem());//Android 8.1.0 console.log("当前微信版本:" + apps.getVersion()); if (apps.getPlatform() == "android") { console.log("android手机 当前系统版本号:" + apps.getSystem().replace("Android", "").replace(" ", "")); //android版本高于6.0.0 if (!versionCompare("6.0.0", apps.getSystem().replace("Android","").replace(" ",""))) { console.log("当前系统版本高于6.0.0"); //位置服务权限 wx.getSetting({ success: function (res) { var statu = res.authSetting; //位置服务授权校验操作 if (!statu['scope.userLocation']) { wx.showModal({ title: '温馨提示', content: '请授予位置服务权限,以便更好的搜索周围设备', success: function (tip) { if (tip.confirm) { //点击确认 开始判断位置服务权限信息 wx.openSetting({ success: function (data) { if (data.authSetting["scope.userLocation"] === true) { wx.showToast({ title: '授权成功', icon: 'success', duration: 1000 }) //授权成功之后,调用自己封装的蓝牙各项操作 bleOperateFun(obj); } else { wx.showToast({ title: '授权失败', icon: 'none', duration: 1000 }); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); } } }) }else{ console.log("点击了取消操作"); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); } } }) }else { //存在权限,调用封装的蓝牙方式继续进行 bleOperateFun(obj); } }, fail: function (res) { wx.showToast({ title: '调用授权窗口失败', icon: 'success', duration: 1000 }); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); } }) } else if (!versionCompare(apps.getSystem().replace("Android", "").replace(" ", "")), "4.3.0") { //系统版本低于4.3的,使用不了ble蓝牙 wx.showModal({ title: '温馨提示', content: '您的手机系统版本较低,无法操作BLE蓝牙设备', showCancel:false, }); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); }else { console.log("系统版本低于6.0.0但高于4.3.0"); //除去android系统的手机(由于最开始过滤了能支持蓝牙的最低微信版本 所以此处无需再判断) bleOperateFun(obj); } } //除android以外的ios或者其他系统 bleOperateFun(obj); }

2、判断蓝牙状态,提示开启蓝牙等

function bleOperateFun(obj){ //1、判断手机蓝牙是否开启 wx.openBluetoothAdapter({ success: function(res) { console.log("初始化蓝牙适配器成功"); //1、开启蓝牙适配器的状态变化监听 wx.onBluetoothAdapterStateChange(function(res){ console.log("蓝牙适配器状态变化",res); // 如果对按钮dis有操作的,需要判断状态进行按钮状态的释放等。 }); //2、开启搜索周围设备的情况监听事件 (扫描 开锁 两次按钮点击 针对同一个设备只执行了一次) wx.onBluetoothDeviceFound(function(res){ console.log("扫描周围设备详情返回:"+JSON.stringify(res)); //判断是否为 "创想物联" 的设备 若是则需要进行连接操作和关闭扫描操作(节省手机资源) res.devices.forEach(device=>{ console.log(device.name +"/"+device.localName); console.log("广播数据:" + apps.ab2hex(device.advertisData)); }); }); // 3、连接状态变化监听 --监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等 wx.onBLEConnectionStateChange(function(res){ console.log("蓝牙设备连接状态监听回调:\n"+JSON.stringify(res)); }); //开启扫描周围设备模式 startScanAroundDevice(obj); }, fail:function(res){ console.log("初始化蓝牙适配器失败") wx.showModal({ title: '温馨提示', content: '请检查手机蓝牙是否打开', showCancel:false, }); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); } }) } 3、扫描周围设备 function startScanAroundDevice(obj) { if (isScaning) { console.log("正在扫描设备。。。。"); return; } wx.startBluetoothDevicesDiscovery({ success: function(res) { console.log("成功开启扫描:" + res); isStartScan = true; isScaning = true; }, fail: function(res) { console.log("扫描操作失败回调"); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); } }); //同时进行定时操作 规定时间内未扫描到设备时,进行关闭扫描操作 if (obj.data.btnText == "扫描") { //扫描操作 不会进行连接 所以时间可以短点 setTimeout(function() { stopScanAroundDevice(obj); }, apps.bleProperties.scanToConnectTimes); } else { setTimeout(function() { stopScanAroundDevice(obj); }, apps.bleProperties.scanTimes); } }

自定义函数中,扫描操作也添加了一个定时任务操作,就是关闭扫描,释放资源。

4、关闭扫描函数 //关闭扫描周围设备操作 function stopScanAroundDevice(obj) { wx.stopBluetoothDevicesDiscovery({ success(res) { console.log(new Date() + "定时关闭扫描返回:" + JSON.stringify(res)); isScaning = false; }, fail: function(res) { console.log("关闭扫描失败回调:" + JSON.stringify(res)); obj.setData({ btnDisabled: false, }); //执行quit机制 quit(obj); } }) } 5、识别设备 在扫描操作执行后,当有设备在手机上识别到时,会触发wx.onBluetoothDeviceFound 监听。

但是,wx.onBluetoothDeviceFound 接口中的 advertisData数据是一种ArrayBuffer格式。解析此类数据时,需要使用以下的函数进行操作。

//广播数据为Array Buffer类型 ArrayBuffer转16进度字符 ab2hex: function(buffer) { var hexArr = Array.prototype.map.call( new Uint8Array(buffer), function(bit) { return ('00' + bit.toString(16)).slice(-2) } ) return hexArr.join(''); }, wx.onBluetoothDeviceFound(function(res) { // 此时的res是一个集合信息,包含很多设备的广播数据,比如广播包等 //{"devices":[{"deviceId":"E0:7D:EA:EB:89:A3","name":"ZN-GS04E","RSSI":-80,"advertisData":{},"advertisServiceUUIDs":["0000CCD0-0000-1000-8000-00805F9B34FB"],"localName":"ZN-GS04E","serviceData":{}}]} //采取如下方式进行遍历 res.devices.forEach(device => { }) })

【注意:】Android系统 deviceId 就是指定设备的 mac 信息;ios系统则是一串随机uuid!

可以将设备mac保存至设备的蓝牙广播字段中。

6、当识别到设备后,此时需要进行连接操作 连接操作使用下列方式: //执行连接操作 连接设备 function startConnectTo(obj) { wx.showLoading({ title: '连接蓝牙设备中...', }); wx.createBLEConnection({ deviceId: obj.data.lockMac, success: function(res) { wx.hideLoading(); wx.showToast({ title: '连接成功', icon: 'success', duration: 1000 }) //更改全局连接状态 isConnected = true; console.log("连接设备成功"); console.log("连接success回调:" + JSON.stringify(res)); //关闭扫描 stopScanAroundDevice(obj); //开启通信服务 startCommitServices(obj); }, fail: function(res) { wx.hideLoading(); wx.showToast({ title: '连接设备失败', icon: 'success', duration: 1000 }) console.log("连接设备失败") console.log("连接fail回调:" + res); obj.setData({ btnDisabled: false, }); //执行 quit 机制 quit(obj); } }) } 7、开启服务(兼容ios),开启notify和特征值数据变化监听 function startCommitServices(obj) { // sendOpenlockKeys(obj); // return; wx.getBLEDeviceServices({ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 deviceId: obj.data.lockMac, success(res) { console.log(JSON.stringify(res)) console.log('device services:', res.services) console.log('device services:', apps.ab2hex(res)) console.log('device services:', apps.ab2hex(res.services)) //获取设备特征对象 wx.getBLEDeviceCharacteristics({ deviceId: obj.data.lockMac, serviceId: apps.bleProperties.bleServiceUUID, success: function(res) { console.log("wx.getBLEDeviceCharacteristics ---->\n" + JSON.stringify(res)) // notify 功能,开启监听 // 需要延迟开启 setTimeout(() => { wx.notifyBLECharacteristicValueChange({ characteristicId: apps.bleProperties.readCharacUUID, deviceId: obj.data.lockMac, serviceId: apps.bleProperties.bleServiceUUID, state: true, type:"notification", // 默认为 indication(有ack) ,notification无ack success:function(res){ console.log("wx.notifyBLECharacteristicValueChange success回执:\n"+JSON.stringify(res)); // // 开启notify监听之后,需要开启特征值数据变更回执 console.log("###################################### 11111111"); wx.onBLECharacteristicValueChange(function(res) { console.log("###################################### 22222222"); console.log("-----> wx.onBLECharacteristicValueChange 监听事件:\n" + JSON.stringify(res)); isOpenCharacValueChange = true; // 写 1800ms setTimeout(() => { sendOpenlockKeys(obj); }, apps.bleProperties.writeSuccessBegainReadTime); }, fail:function(){ wx.showModal({ title: '温馨提示', content: '开启notify失败!', showCancel: false }); obj.setData({ btnDisabled: false, }); quit(obj); } }) }, apps.bleProperties.bleNotifyTimeout); }, fail: function() { wx.showModal({ title: '温馨提示', content: '获取特征对象失败!', showCancel: false }); obj.setData({ btnDisabled: false, }); quit(obj); } }) }, fail: function() { wx.showModal({ title: '温馨提示', content: '获取服务失败!', showCancel: false }); obj.setData({ btnDisabled: false, }); quit(obj); } }) }

【注意:】开启通信服务后,不要立即去开启notify,不然几率报错!

8、发送数据操作 发送数据操作,使用如下函数: function sendOpenlockKeys(obj) { console.log("sendOpenlockKeys"); //console.log("加密后的长度--->" + buffer.length); //向设备发送开锁命令(传递的应该是数组数据) writeCharacVal(obj, buffer); } //发送开锁命令 function writeCharacVal(obj, sendValue) { console.log("准备向设备发送信息"); wx.writeBLECharacteristicValue({ deviceId: obj.data.lockMac, serviceId: apps.bleProperties.bleServiceUUID, characteristicId: apps.bleProperties.writeCharacUUID, value: sendValue, success: function(res) { console.log("发送开锁命令成功回调:\n" + JSON.stringify(res)); isFirstWrite = true; }, fail(res) { console.log("写数据失败回调" + res); console.log("发送命令次数:" + isFirstWriteNum); wx.showModal({ title: '温馨提示', content: '发送开锁命令失败!', showCancel: false, }) quit(obj); } }) }

注意发送的数据类型为ArrayBuffer,需要对字符串数据进行转换:

strToArrayBuffer: function(aes, str) { //首先将str转化为数组 var strtoHexArray = aes.hex_to_bytes(str); //取一半数据的长度作为arraybuffer的长度 var buffer = new ArrayBuffer(str.length >> 1); var bufView = new DataView(buffer); //保存数据至arraybuffer中 for (var i = 0, len = (str.length >> 1); i > 1); for (var i = 0; i > 1] = parseInt(str.substr(i, 2), 16); } return bytes; } 9、资源释放 //quit机制 function quit(obj) { // 如果开启了notify,则需要在quit中释放资源 if(isOpenCharacValueChange){ wx.offBLECharacteristicValueChange({ success: function(res) { console.log("quit wx.offBLECharacteristicValueChange 成功回调 清理手机蓝牙资源"); console.log(JSON.stringify(res)); }, fail(res) { console.log("wx.offBLECharacteristicValueChange 资源失败回调 " + res); } }) } //如果连接上了 需要断开连接操作 if (isConnected) { wx.closeBLEConnection({ deviceId: obj.data.lockMac, success(res) { console.log("quit() 断开连接操作成功回调"); isConnected = false; }, fail(res) { console.log("quit() 断开连接操作失败回调"); } }); } //如果扫描操作执行了的 需要释放手机蓝牙的资源 if (isStartScan) { wx.closeBluetoothAdapter({ success: function(res) { console.log("quit wx.closeBluetoothAdapter 成功回调 清理手机蓝牙资源"); console.log(JSON.stringify(res)); }, fail(res) { console.log("清理手机端 蓝牙 资源失败回调 " + res); } }) } //不管操作进行到哪步 quit操作后 都需要释放按钮为 可点击状态 obj.setData({ btnDisabled: false, }); } 关于notify开启成功后,onBLECharacteristicValueChange无法监听的问题

在这里插入图片描述 【解决方式】

可以和设备开发工程师商讨兼容性解决方式。 比如:写一次其他信息,再写一次真实数据信息。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3