https://www.cnblogs.com/ckfuture/p/16450418.html

https://www.cnblogs.com/yangxiaobai123/p/16021058.html

字符串转base64:https://www.cnblogs.com/sunny3158/p/17312158.html 

将 ArrayBuffer 对象转成 Base64 字符串:基础 - uni.arrayBufferToBase64 - 《uni-app API 文档》 - 书栈网 · BookStack 

ArrayBuffer:https://zhuanlan.zhihu.com/p/655456833 

最近在做一个项目,要求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。否则传输的内容将被截取,造成传输信息不完整。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部