uni 您所在的位置:网站首页 苹果蓝牙怎么和安卓蓝牙连接 uni

uni

2024-05-26 06:30| 来源: 网络整理| 查看: 265

前言: 因为需要开发与蓝牙设备控制相关,但是这不是常用的蓝牙打印,并且是由原生安卓已经做好的,但是需要移植到多平台(小程序 等)都可以使用所以就要移植成 uni-app ,所以这个是按照uni-app的蓝牙设备完成的。 以下涉及到的 有 蓝牙的连接 、 蓝牙的数据byte构造、数组构造的方法

uni-app蓝牙相关的API:https://uniapp.dcloud.io/api/system/ble https://uniapp.dcloud.io/api/system/bluetooth

一、蓝牙的连接 // 初始化方法 initializeBlue () { let _this = this //在页面加载时候初始化蓝牙适配器 uni.openBluetoothAdapter({ success:(res)=> { //已打开 uni.getBluetoothAdapterState({//蓝牙的匹配状态 success:(res1)=>{ console.log(res1,'本机设备的蓝牙已打开') // 开始搜索蓝牙设备 this.startBluetoothDeviceDiscovery() }, fail(error) { uni.showToast({icon:'none',title: '查看手机蓝牙是否打开'}); } }); }, fail:err=>{ //未打开 uni.showToast({icon:'none',title: '查看手机蓝牙是否打开'}); } }) }, // 开始搜索蓝牙设备 startBluetoothDeviceDiscovery(){ uni.startBluetoothDevicesDiscovery({ success: (res) => { console.log('startBluetoothDevicesDiscovery success', res) // 发现外围设备 this.onBluetoothDeviceFound() },fail:err=>{ console.log(err,'错误信息') } }) }, // (发现外围设备,如果你的设备是通过扫码获取到mac格式的id的话 可以不需要这个发现外围设备) // 发现外围设备 onBluetoothDeviceFound() { uni.onBluetoothDeviceFound((res) => { console.log(JSON.stringify(res.devices)) if(this.list.indexOf(res.devices[0].deviceId)==-1){ this.list.push({ name:res.devices[0].name, deviceId:res.devices[0].deviceId }) } }) },

======== 以上的代码是初始化的 =======

以下代码 可以根据自身情况运用上面 文档的API(我这里用的是扫码后获取到的id,这个id需要我转成MAC格式的) MAC格式,例如: 扫码获取到的id是 70512154dd9c,那么需要转成的MAC格式 就变成了 70:51:21:54:dd:9c 就是在每两个加“ : ”号 。 这里也把 转成这个格式的方法也写一下吧

// id 获取回来的id 如果直接扫码获取到的就是MAC格式 或者 直接是附近蓝牙直接点击链接的话 那就不需要这个 id.replace(/(.{2})/g,'$1:').slice(0,-1)

进入正题--------- (注意:以下方法中MTU是设置最大传输值,为了防止例如[12,45,5,1,23,12…],蓝牙只获取到[12,45,5]这种情况)

//选择设备连接吧deviceId传进来 createBLEConnection(maIp){ let _le = this this.deviceId = maIp // 如果不是MAC地址 replace(/(.{2})/g,'$1:').slice(0,-1) //连接蓝牙 uni.createBLEConnection({ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 deviceId: maIp, // 如果不是MAC地址 replace(/(.{2})/g,'$1:').slice(0,-1) success(res) { console.log(res) console.log("蓝牙设备连接成功") _le.setMaxMTU() // 因为蓝牙默认的MTU传输值可能不够大,导致传输数据丢失 所以执行该方法扩大传输MTU },fail(res) { uni.showToast({ icon:'none', title: '蓝牙连接失败', duration: 2000 }); console.log("蓝牙连接失败",res) } }) }, // 设置最大MTU值 (可以参照文档) setMaxMTU () { let _this = this uni.setBLEMTU({ deviceId:this.deviceId, mtu:200, success(res) { console.log(res) console.log("设置最大值成功") // this.stopBluetoothDevicesDiscovery() // _le.getBLEDeviceServices() _this.getBluetoothDevices() },fail(res) { uni.showToast({ icon:'none', title:'设备初始化失败' }) console.log("设置最大值失败!!!",res) } }) }, //获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。 getBluetoothDevices() { console.log("获取蓝牙设备"); uni.getBluetoothDevices({ success: res => { console.log('获取蓝牙设备成功:'); console.log(res.devices); res.devices.forEach(item => { if (item.deviceId === this.deviceId) { this.serviceId = item.advertisServiceUUIDs[0] this.getBLEDeviceCharacteristics() } }) } }); }, //获取蓝牙特征 getBLEDeviceCharacteristics(){ console.log("进入特征",this.deviceId,this.serviceId); setTimeout(()=>{ uni.getBLEDeviceCharacteristics({ // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 deviceId:this.deviceId, // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取 serviceId:this.serviceId, success:(res)=>{ console.log(res,'特征getBLEDeviceCharacteristics') this.characteristics = res.characteristics this.readUUID = res.characteristics[0].uuid this.writeUUID = res.characteristics[1].uuid console.log(this.characteristics) res.characteristics.forEach((item)=>{ if(item.uuid.indexOf("0000FFF1") !== -1){ this.characteristicId = item.uuid //console.log('characteristicId:', item.uuid) //利用传参的形势传给下面的notify,这里的uuid如果都需要用到,就不用做判断了,建议使用setTimeout进行间隔性的调用此方法 this.notifyBLECharacteristicValueChange(item.uuid) } }) }, fail:(res)=>{ console.log(res) } }) },1000) },

// 重点来了,需要开启 监听才可以监听到 蓝牙根据你传过去的数据 传输回来的数据 所以

// 启用 notify 功能 监听 notifyBLECharacteristicValueChange(characteristicId){ console.log(characteristicId,'characteristicId') uni.notifyBLECharacteristicValueChange({ state: true, // 启用 notify 功能 // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接 deviceId:this.deviceId, // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取 serviceId:this.serviceId, // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取 characteristicId:characteristicId, success:(res)=> { console.log(res) // console.log(this.characteristicId) console.log('notifyBLECharacteristicValueChange success', res.errMsg) uni.onBLECharacteristicValueChange(characteristic => { console.log('监听低功耗蓝牙设备的特征值变化事件成功',characteristic); var array = new Uint8Array(characteristic.value); // 这是监听蓝牙返回的数据 console.log('包' + array); }) }, fail:(res)=> { console.log('notifyBLECharacteristicValueChange fail', res.errMsg) } }) },

上面的代码 是我根据自身项目 作出了相对应的调整过的,仅供参考。 也可以参考一下demo 这个博主的 https://blog.csdn.net/qq_42783654/article/details/115324789 好了 到这里 才是我噩梦的开始。

二、 数据的传递

以下是 你把构建好的byte数组 传进该方法 然后 把Byte数组传输给蓝牙,蓝牙会在 第 一 点中的监听方法返回蓝牙设备响应后返回的值。你可以使用 我下面为你们准备好的 Byte数组 和 字符串方法进行解析。

//写入蓝牙 writeBLECharacteristicValue(b) { console.log("传进来的B~~~~~",b) // 向蓝牙设备发送一个0x00的16进制数据 let buffer = new ArrayBuffer(b.length) let dataView = new DataView(buffer) b.forEach((item,index) => { dataView.setUint8(index,item) }) uni.writeBLECharacteristicValue({ deviceId: this.deviceId, serviceId: this.serviceId, characteristicId: this.writeUUID, value:buffer, success(res) { console.log('writeBLECharacteristicValue success', res) }, fail(res) { console.log(JSON.stringify(res)) console.log(JSON.stringify(buffer)) } }) },

很多连接了蓝牙之后 数据的传递就有问题了,因为蓝牙接收的是 byte数组 ,所以 你也需要按照后端大哥调试好的设备文档 你传输相对应的 byte数组 给蓝牙设备接收 才能做出相对应的处理

蓝牙连接 CRC16值肯定是少不了的了,网上的方法也很多,但是项目需求不一样,导致CRC16构造出来的值也不一样,移植项目中的CRC16构造需要设置相对应的初始值。以下是我找到的方法 注释 有详解

这是从另外一个博主身上学回来 然后根据自身 作出微调 和 注释的CRC16。 https://www.jianshu.com/p/75fa84050f0a

//CRC蓝牙校验 crc16(buffer) { var crc = 0x000; // 这是 设置初始值的 可以根据自己的CRC16协议进行调整 var odd; for(var i = 0; i odd = crc & 0x8000; crc = crc if(typeof isReverse == 'undefined') { isReverse = true; } var hi = arr[0], lo = arr[1]; return this.padLeft((isReverse ? hi + lo * 0x100 : hi * 0x100 + lo).toString(16).toUpperCase(), 4, '0'); }, padLeft(s, w, pc) { if (pc == undefined) { pc = '0'; } for (var i = 0, c = w - s.length; i var str = ""; for (var i = 0; i //此处填坑,当byte因为符合位导致数值为负时候,需要对数据进行处理 tmp = (255 + num + 1).toString(16); } else { tmp = num.toString(16); } if (tmp.length == 1) { tmp = "0" + tmp; } if(i>0){ str += ":"+tmp; // 可以修改 : 成你需要的间隔符号,如果不需要间隔符号那就空着 }else{ str += tmp; } } return str; }, //比如 [12,5,8,41,2] // 返回的是 12:5:8:41:2 // byte转纯字符串 BytesToStr(arrBytes){ var str = ""; for (var i = 0; i //此处填坑,当byte因为符合位导致数值为负时候,需要对数据进行处理 tmp = (255 + num + 1).toString(16); } else { tmp = num.toString(16); } if (tmp.length == 1) { tmp = "0" + tmp; } if(i>0){ str += tmp; }else{ str += tmp; } } return str; }, // !!!!重点!!!! 很多时候因为你返回的16进制 是 2个数字为 1 字节 // 比如 442288C7 这种,用简单的字符转byte 会把字符串 44 分开编译成两个Byte数组 // 以下方法是 44 22 88 C7 这样为一组编译 // 字符 转 16进制Byte // 两个为一组 bin2Str(str){ let a = [] let arr = [] for (var i = 0; i a.forEach(item => { arr.push(parseInt(item,16)) }) } else { return [] } return arr }, // Hex字符 转换成 Byte HexString2Bytes(str) { var pos = 0; var len = str.length; if (len % 2 != 0) { return null; } len /= 2; var arrBytes = new Array(); for (var i = 0; i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有