1,开启蓝牙适配器初始化蓝牙模块
openBluetoothAdapter() { let that = this; uni.openBluetoothAdapter({ success: (res) => { this.startBluetoothDevicesDiscovery(); }, fail: (res) => { console.log(res) uni.showModal({ title: '提示', content: '请开启本机蓝牙' }); if (res.errCode === 10001) { console.log('111') //监听蓝牙适配器是否打开,若打开则自动搜索蓝牙设备 uni.onBluetoothAdapterStateChange(function(res) { if (res.available) { that.startBluetoothDevicesDiscovery();//开启蓝牙设备搜索 } }); } }, }); },
2.开启蓝牙设备搜索
//开启蓝牙设备搜索 startBluetoothDevicesDiscovery() { uni.startBluetoothDevicesDiscovery({ allowDuplicatesKey: true, //允许重复上报同一个设备 success: (res) => { uni.showLoading({ title: "正在搜索设备", duration: 2000 }); this.onBluetoothDeviceFound();//监听新设备事件 }, }); },
3.监听寻找的新设备事件
//监听寻找到新设备的事件 onBluetoothDeviceFound() { let that = this; uni.onBluetoothDeviceFound((res) => { if (res) { uni.hideLoading(); } res.devices.forEach(device => { //过滤掉没有名字的设备 if (!device.name && !device.localName) { return }; //这么操作是为了去除重复 const foundDevices = that.devices //将数据中的数组复制一份,利用动态绑定方式,不断复制最新的数组 const idx = that.inArray(foundDevices, 'deviceId', device.deviceId) if (idx === -1) { //TSH-01(BLE) 蓝牙设备型号 根据需求选择设备型号 if (device.name == "TSH-01(BLE)") { console.log(device) that.handleData02(device.advertisData);//蓝牙接收的数据 that.devices.push(device); //数组里没有的的就向里面添加数据,保证没有重复 } // that.devices.push(device); } }) }); },
3.点击某个蓝牙设备连接蓝牙
createBLEConnection(item) { let that = this; that.$refs.loading.open(); this.chooseDevice = item; // item 包含 item.name(蓝牙名称) 和 item.deviceId(蓝牙MAC) uni.createBLEConnection({ deviceId:item.deviceId, success: (res) => { setTimeout(() => { console.log("连接成功----",res); uni.showModal({ title:'提示', content:'连接成功' }) uni.stopBluetoothDevicesDiscovery(); //停止搜索蓝牙设备 that.getBLEDeviceServices(item.deviceId);//获取服务 that.$refs.loading.close(); }, 1000); }, fail:(err)=>{ that.$refs.loading.close(); console.log("连接失败----",err); return } }) },
4.获取服务
getBLEDeviceServices(deviceId) { uni.getBLEDeviceServices({ deviceId:deviceId,//连接设备的devideid值 success: (res) => { //serviceId固定,获取蓝牙设备某个服务中所有特征值【读写属性的】 this.getBLEDeviceCharacteristics(deviceId, this.serviceId) }, fail:(err)=>{ uni.showToast({ title:'获取服务失败', icon:'error', duration:2000 }) console.log("获取服务失败----",err); return } }) },
5.如果一个蓝牙设备需要进行数据的写入以及数据传输,就必须具有某些特征值,所以通过上面步骤获取的id可以查看当前蓝牙设备的特征值
getBLEDeviceCharacteristics(deviceId, serviceId) { var that = this; uni.getBLEDeviceCharacteristics({//设备id与服务id必须要给,特征值id先不用获取,直接写死 deviceId,serviceId, success: (res) => { if(res.characteristics[0].properties.read){ uni.readBLECharacteristicValue({ deviceId,serviceId,characteristicId:this.characteristicId, success(res) { // console.log('特征值读取结果:', res) } }); } if(res.characteristics[0].properties.write){} //确保对应服务id下的特征值id具备监听数据变化的特性 if (!res.characteristics[0].properties.notify || !res.characteristics[0].properties.indicate) { uni.notifyBLECharacteristicValueChange({ deviceId,serviceId,characteristicId: this.characteristicId, state: true,//是否启用notify通知 success:(res)=>{ //--------------- } }) } //--------------- }, fail(res) { console.error('获取蓝牙设备特征值失败', res) } }) //点击发送命令(连接上后就发送连接指令为了清空设备上的数量) that.beginRopeSkipping('xxxxxxxx', deviceId); //添加断开验证 uni.onBLEConnectionStateChange(function (res) { if(!res.connected){ console.log("设备已断开") } }) //接收数据 uni.onBLECharacteristicValueChange((characteristic) => { if(characteristic.characteristicId == "0000AE02-0000-1000-8000-00805F9B34FB"){ if("a5d2100100220031000000000000002f0e7723".length == this.ab2hex(characteristic.value).length){ that.handleData(characteristic);//接受的设备数据:学名广播 } } }) },
6.接收设备数据
handleData(characteristic){ var that = this; var rowData = this.ab2hex(characteristic.value);//buffer码转换成16进制字符串 // console.log("----",rowData) var model0 = rowData.substring(2,4); // 状态 截取16进制字符串中的需要的字符串,得到的是16进制码 var model1 = rowData.substring(6,8); // 模式 var model2 = rowData.substring(8,12); // 时间 parseInt(model2, 16); var model3 = rowData.substring(12,16); // 次数 parseInt(model3, 16) var model4 = rowData.substring(16,20); // 失误次数 //跳绳参数 console.log("时间",parseInt(model2, 16))//将16进制转换成10进制 console.log("成功次数",parseInt(model3, 16)) console.log("失误次数",parseInt(model4, 16)) console.log("---------------------------") },
7.buffer转换16进制字符串
// ArrayBuffer转16进制字符串示例 ab2hex(buffer) { var hexArr = Array.prototype.map.call( new Uint8Array(buffer), function (bit) { return ("00" + bit.toString(16)).slice(-2); } ); return hexArr.join(""); },
8.发送指令
//点击按钮发送指令,指令为 16进制模式 DAOJISHI(key){ if(key == 1){ this.writeBlueToothValue('xxxxxxxxxxx','');//30秒 }else if(key == 2){ this.writeBlueToothValue('xxxxxxxxxxx','');//1 分钟 }else if(key == 3){ this.writeBlueToothValue('xxxxxxxxxxx','');//倒计数 100 次 } }, writeBlueToothValue(sendData){ let that = this; this.writeValue(sendData,that.chooseDevice.deviceId);//跳绳模式指令 需要deviceid setTimeout(()=>{ that.writeValue('xxxxxxx',that.chooseDevice.deviceId);//开始跳绳指令 },800) },
9.开始命令(上面的连接成功后开始指令)
beginRopeSkipping(sendData,deviceId){ this.writeValue(sendData,deviceId); },
10.向蓝牙设备发送数据
//向蓝牙设备发送一个数据(期间要进行数据转换) writeValue(sendData,deviceId) { var arrayBuffer = new Uint8Array(sendData.match(/[\da-f]{2}/gi).map(function (h) { return parseInt(h, 16) })) arrayBuffer = arrayBuffer.buffer; uni.getBLEDeviceCharacteristics({ //设备id与服务id必须要给,特征值id先不用获取,直接写死 deviceId:deviceId, serviceId:this.serviceId, success: (res) => { for (let i = 0; i < res.characteristics.length; i++) { let item = res.characteristics[i]; if (item.properties.write) { uni.writeBLECharacteristicValue({ deviceId: deviceId, serviceId: this.serviceId, characteristicId: item.uuid, value: arrayBuffer, success :(res)=> { console.log('发送数据 Success', res); return; }, fail:(res)=>{ console.log('发送数据 fail',res) }, complete:(res)=>{ //buffer本身是arraybuffer(arraybuffer要转换为16进制) // let sixNumber=this.ab2hex(arrayBuffer); console.log(res) } }) } break; } }, }) this.sendData = '' },