uni-app 蓝牙传输
最近在做一个项目,要求app通过蓝牙连接设备并将报文传输至设备中,在这个过程踩过了几个坑,总结如下:
根据uni-app官网API主要涉及到“蓝牙”和“低功耗蓝牙”两个部分。
主要步骤:
步骤1:初始化蓝牙模块 openBluetoothAdapter
$openBluetoothAdapter(){ uni.openBluetoothAdapter({ success: (res) => { //初始化成功,搜索设备 console.log('openBluetoothAdapter success', res); uni.showLoading({ title: '搜索设备中' }); setTimeout(()=>{ this.baseList=[];//每次扫码清空设备列表,不然会导致重复 this.$startBluetoothDevicesDiscovery();//扫码蓝牙设备 },100); //定时关闭搜索设备 setTimeout(()=>{ this.$stopBluetoothDevicesDiscovery(); uni.hideLoading(); },10*1000); }, fail: (res) => { uni.showToast({ title: '请打开蓝牙', duration: 1000 }); if (res.errCode === 10001) { //监听蓝牙适配器状态变化事件 uni.onBluetoothAdapterStateChange(function(res){ console.log('onBluetoothAdapterStateChange', res); if (res.available) { //开始扫描 this.$startBluetoothDevicesDiscovery() } }) } } }) },
步骤2:搜索附近的蓝牙外围设备 startBluetoothDevicesDiscovery
//2.搜索附近的蓝牙外围设备 $startBluetoothDevicesDiscovery(){ if (this._discoveryStarted) { return; } this._discoveryStarted = true; //开始搜寻附近的蓝牙外围设备 uni.startBluetoothDevicesDiscovery({ allowDuplicatesKey: true, success: (res) => { console.log('startBluetoothDevicesDiscovery success', res); //监听寻找到新设备的事件 this.$onBluetoothDeviceFound() }, fail:err=>{ console.error("startBluetoothDevicesDiscoveryErr",err); uni.showToast({ icon:'none', duration:2000, title:"请检查蓝牙状态", }); } }) },
步骤3:监听寻找到新设备 onBluetoothDeviceFound
$onBluetoothDeviceFound(){ let that =this; //监听寻找到新设备的事件 uni.onBluetoothDeviceFound(function(res){ res.devices.forEach(device => { if (!device.name && !device.localName) { return; } //添加蓝牙设备列表 let oneBluetooth={ deviceId: device.deviceId, name: device.name, RSSI:device.RSSI, localName:device.localName } //判断是否存在 if(that.bluetoothIndex.indexOf(device.deviceId) ==-1){ that.baseList.push(oneBluetooth); that.bluetoothIndex.push(device.deviceId); } //如果名字相同连接设备 //if(device.name == devicename){ //$createBLEConnection(device.deviceId); //} }) }) },
步骤4:创建连接蓝牙事件 createBLEConnection
$createBLEConnection(deviceId){ let that=this; //1)判断设备是否处于连接状态 if(that.Connecting){ uni.showToast({ icon:'none', duration:2000, title:"设备已连接", }); return } //2)创建连接 uni.showLoading({ title: '设备连接中', mask:true, }); uni.createBLEConnection({ deviceId:deviceId, success: (res) => { that._deviceId = deviceId; //不延迟造成获取不到服务!!!!,我走过的坑!!! setTimeout(function() { //获取设备的蓝牙服务 that.$getBLEDeviceServices(deviceId); //关闭等待提示 setTimeout(function () {uni.hideLoading();}, 100); }, 7000); }, fail: (err) =>{ console.log(err); } }); //3)设置MTU,否则传输报文不全,默认是23bytes,但是蓝牙本身是需要3bytes,故而只能传输20bytes setTimeout(()=>{ console.log('deviceId>>>',deviceId); uni.setBLEMTU({ deviceId:deviceId, mtu:255, success:(res)=>{ console.log('设置MTU最大值成功',res); }, fail:(res)=>{ console.log('设置MTU最大值失败',res); } }); },9000); //4)关闭搜索 this.$stopBluetoothDevicesDiscovery(); },
步骤5:获取蓝牙设备的所有服务 getBLEDeviceServices
$getBLEDeviceServices(deviceId){ //获取蓝牙设备所有服务(service) uni.getBLEDeviceServices({ deviceId, success: (res) => { console.log('250res.services>>>',res.services); for (let i = 0; i < res.services.length; i++) { if (res.services[i].isPrimary) { this.$getBLEDeviceCharacteristics(deviceId, res.services[i].uuid); return; } } } }); },
步骤6:获取蓝牙设备某个服务中所有特征值(characteristic)getBLEDeviceCharacteristics
$getBLEDeviceCharacteristics(deviceId,serviceId){ let that = this; //获取蓝牙设备某个服务中所有特征值(characteristic)。 uni.getBLEDeviceCharacteristics({ deviceId, serviceId, success: (res) => { console.log('288getBLEDeviceCharacteristics success', res.characteristics); for (let i = 0; i < res.characteristics.length; i++) { let item = res.characteristics[i] //if (item.properties.read) { //读取低功耗蓝牙设备的特征值的二进制数据值。1 uni.readBLECharacteristicValue({ deviceId, serviceId, characteristicId: item.uuid, }) //} if (item.properties.write) { this._deviceId = deviceId; this._serviceId = serviceId; this._characteristicId = item.uuid; //写入请求数据 this.$writeBLECharacteristicValue(); } //if (item.properties.notify || item.properties.indicate) { //启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。 uni.notifyBLECharacteristicValueChange({ deviceId, serviceId, characteristicId: item.uuid, state: true, success(res) { // console.log('notifyBLECharacteristicValueChange success:' + res.errMsg); // console.log(JSON.stringify(res)); uni.onBLECharacteristicValueChange(characteristic => { console.log('监听低功耗蓝牙设备的特征值变化事件成功>>'); //将字节转换成16进制字符串 var data = ab2hex(characteristic.value) //将16进制转成字符串 let newdataStr = Buffer.from(data,'hex');//先把数据存在buf里面 //that.btvalue=newdataStr.toString("utf-8");//使用toString函数就能转换成字符串 //设备返回SN that.SN=newdataStr.toString("utf-8"); console.log('设备返回SN>>>',that.SN); //根据返回的数据处理设备类型和显示的输入区域----------------- that.getEquType(that.SN); }); } }); //} } }, fail(res) { console.error('getBLEDeviceCharacteristics', res) } }) },
步骤7:向蓝牙设备发送一个16进制数据
$writeBLECharacteristicValue(){ let buffer = new ArrayBuffer(1) let dataView = new DataView(buffer); dataView.setUint8(0, 0);//0x61 | 0 uni.writeBLECharacteristicValue({ deviceId: this._deviceId, serviceId: this._serviceId,//"0000FE61-0000-1000-8000-00805F9B34FB", characteristicId: this._characteristicId, value: buffer, success: function(res){ console.log('350',res); }, fail: function(res){ console.log(res); } }) },
步骤8:向蓝牙设备发送字符串数据 writeBLECharacteristicValueString
$writeBLECharacteristicValueString(str){ // 发送方式一 let buffer = new ArrayBuffer(str.length); let dataView = new DataView(buffer); for (let i in str) { dataView.setUint8(i, str[i].charCodeAt() | 0); //打印二进制字节 //console.log('dataView.getUint8(i)>>',dataView.getUint8(i)); } //延迟发送指令 setTimeout(()=>{ uni.writeBLECharacteristicValue({ deviceId: this._deviceId, serviceId: this._serviceId, characteristicId: this._characteristicId,//"0000FE61-0000-1000-8000-00805F9B34FB",//, value: buffer, success: function(res){ console.log("命令写入成功",res); }, fail: function(res){ console.error("命令写入失败",res); } }); },2000); },
步骤9:关闭搜索 stopBluetoothDevicesDiscovery
$stopBluetoothDevicesDiscovery(){ //关闭搜索 uni.stopBluetoothDevicesDiscovery({ success(res) { this._discoveryStarted=false; } }) },
步骤10:断开蓝牙设备连接 closeBLEConnect
$closeBLEConnect(deviceId){ uni.closeBLEConnection({ deviceId, success:res=>{ this.deviceId = ""; console.log("断开成功",res); }, fail:err=>{ console.error("断开错误",err); } }) },
需要注意的是:
1)和蓝牙设备通讯不能太频繁。
2)写入数据时候要注意特性值UUID。
3)写入数据超过20bytes时候需要设置MTU。否则传输的内容将被截取,造成传输信息不完整。
本文参考:https://blog.csdn.net/qq_33259323/article/details/105609275
https://www.jianshu.com/p/c627ddc7862d
https://uniapp.dcloud.io/api/system/bluetooth.html
https://uniapp.dcloud.io/api/system/ble.html
分类:
uni-app
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战