xuewenhui
xuewenhui
  • 发布:2020-05-19 16:06
  • 更新:2020-09-28 10:56
  • 阅读:2408

【报Bug】低功耗蓝牙多次成队创建连接与关闭蓝牙连接后,会存在多个连接实例

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: win10

HBuilderX类型: 正式

HBuilderX版本号: 2.7.5

手机系统: Android

手机系统版本号: Android 6.0

手机厂商: 华为

手机机型: 荣耀10

页面类型: vue

打包方式: 云端

项目创建方式: HBuilderX

示例代码:
<script>  

    import ble from '../../common/ble.js'  
    import mlib from '../../common/mlib.js'  

    export default{  
        data() {  
            return {  
                deviceDataServiceUUID:'0000fe60-0000-1000-8000-00805f9b34fb',  
                deviceDataInCharacterisicUUID:'0000fe61-0000-1000-8000-00805f9b34fb',  
                deviceDataOutCharacteisicUUID:'0000fe62-0000-1000-8000-00805f9b34fb',  
                valueChangeData:'',  
                connectDevId:'', //选择连接的设备ID  
                bleButtonText:'点击搜索附近的蓝牙设备',  
                bleDeviceList:[],  

                bleIsOpenAdapter:false, //蓝牙适配器是否开启  
                bleIsEnableScanf:false,//蓝牙是否开启搜索  
                bleIsConnected:false,//蓝牙是否连接  
                bleIsReady:false,//蓝牙是否就绪  

                ble_TxMsgQueue:[],//发送消息缓存队列  

                txCtrl:{  
                    txIntervalMs:50, //发送间隔(单位:ms)  
                    isTxEmptr:true, //发送空标志  
                    retryTimerId:0,//重发超时定时器ID  
                    isEnableRetryTimer:false, //使能重发定时器  
                    txTimerId:0, //发送等待间隔定时器ID,蓝牙特征一次最多只能写入20字节,并且必须要等蓝牙驱动将数据发送完成后才能再次写入  
                    isEnableTxTimer:false, //使能发送定时器  
                    msgId:null, //当前正在发送的消息ID  
                    buffer:null, //单个消息缓存,需要切片为20个字节发送  
                    offset:0,  //发送偏移  
                    residue:0, //剩余长度  
                    retry:0,   //重发次数  
                },  

                rxCtrl:{  
                    rxIntervalMs:100,  
                    isEnableRxTimer:false,  
                    timerId:0,  
                    buffer:[],//单个消息接收缓存  
                }  
            }  
        },  

        methods:{  

            tapQuery(item) {  
                this.connectDevId = this.bleDeviceList[item].deviceId;  
                console.log('选择设备ID:' + this.connectDevId);  
                if ( this.bleIsOpenAdapter ){  
                    if ( !this.bleIsConnected ){  
                        this.createBLEConnection();  
                    }else{  
                        console.log('蓝牙已经连接');  
                    }  
                }else{  
                    console.log('未获取蓝牙适配器');  
                }  
            },  

            onBleButton(){  
                if ( this.bleIsOpenAdapter ){  
                    if ( this.bleIsConnected ){  
                        console.log('用户操作断开蓝牙连接');  
                        this.closeBLEConnection();  
                    }else{  
                        this.startBluetoothDevicesDiscovery();  
                    }  
                }else{  
                    console.log('用户操作获取适配器')  
                    this.openBluetoothAdapter();  
                }  
            },  

            /**  
             * 获取适配器状态  
             */  
            getBluetoothAdapterState(){  
                plus.bluetooth.getBluetoothAdapterState({  
                    success: res => {  
                        console.log(JSON.stringify(res));  
                        this.bleIsOpenAdapter = true;  
                        if ( !this.bleIsEnableScanf ){  
                            this.startBluetoothDevicesDiscovery();  
                        }else{  
                            console.log('蓝牙已开启搜索...');  
                        }  
                    },  
                    fail: e => {  
                        initTypes(e.errCode);  
                    }  
                })  
            },  

            /**  
             * 打开蓝牙适配器  
             */  
            openBluetoothAdapter(){  
                plus.bluetooth.openBluetoothAdapter({  
                    success: e => {  
                        console.log(JSON.stringify(e));  
                        this.getBluetoothAdapterState();  
                    },  
                    fail: e => {  
                        console.log(e);  
                        initTypes(e.code);  
                    }  
                })  
            },  

            /**  
             *  断开蓝牙模块  
             */  
            closeBluetoothAdapter(OBJECT) {  
                plus.bluetooth.closeBluetoothAdapter({  
                    success: res => {  
                        this.bleIsOpenAdapter = false;  
                        console.log('断开蓝牙模块成功');  
                    }  
                });  
            },  

            /**  
             * 开始搜索蓝牙设备  
             */  
            startBluetoothDevicesDiscovery(){  
                plus.bluetooth.startBluetoothDevicesDiscovery({  
                    success: e => {  
                        console.log('成功开启蓝牙搜索...');  
                        this.bleButtonText = '蓝牙正在搜索中...';  
                        this.bleIsEnableScanf = true;  
                        this.onBluetoothDeviceFound(); //监听搜索结果  
                        setTimeout(()=>{  
                            this.stopBluetoothDevicesDiscovery();  
                        }, 30000);  
                    },  
                    fail: e => {  
                        initType(e.errCode);  
                    }  
                });  
            },  

            /**  
             * 停止搜索蓝牙设备  
             */  
            stopBluetoothDevicesDiscovery() {  
                if ( this.bleIsEnableScanf ){  
                    plus.bluetooth.stopBluetoothDevicesDiscovery({  
                        success: e => {  
                            this.bleIsEnableScanf = false;  
                            if ( !this.bleIsConnected ){  
                                this.bleButtonText = '点击搜索附近的蓝牙设备';  
                            }  
                            console.log(e);  
                        },  
                        fail: e => {  
                            console.log(e);  
                            initTypes(e.errCode);  
                        }  
                    });  
                }  
            },  

            /**  
             * 注册搜索发现新的设备回调  
             */  
            onBluetoothDeviceFound(){  
                plus.bluetooth.onBluetoothDeviceFound(devices => {   
                    this.getBluetoolDevice(); //获取所有发现的蓝牙设备  
                });  
            },  

            /**  
             * 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。  
             */  
            getBluetoolDevice(){  
                plus.bluetooth.getBluetoothDevices({  
                    success: res => {  
                        //console.log(res);  
                        var list = [];  
                        for(var i = 0; i<res.devices.length; i++){  
                            if ( res.devices[i].name.length != 0 ){  
                                list.push(res.devices[i])  
                            }  
                        }  
                        this.bleDeviceList = list;  
                    },  
                    fail: e => {  
                        console.log(e);  
                        initTypes(e.errCode);  
                    }  
                });  
            },  

            /**  
             * 连接低功耗蓝牙  
             */  
            createBLEConnection() {  
                let devid = this.connectDevId;  
                this.onBLEConnectionStateChange() //监听连接状态  
                console.log('创建BLE连接')  
                uni.createBLEConnection({  
                    deviceId: devid,  
                    success: res => {   
                        //调用连接 API成功  
                        console.log(res);  
                    },  
                    fail: e => {  
                        initTypes(e.errCode);  
                    }  
                });  
            },  

            /**  
             * 断开与低功耗蓝牙设备的连接  
             */  
            closeBLEConnection() {  
                let deviceid = this.connectDevId;  
                console.log('断开BLE连接:' + deviceid);  
                uni.closeBLEConnection({  
                    deviceId: deviceid,  
                    success: res => {  
                        console.log(res);  
                    },  
                    fail: e => {  
                        console.log(e);  
                        initTypes(e.errCode);  
                    }  
                });  
            },  

            /*  
             * 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等  
             */  
            onBLEConnectionStateChange() {  
                plus.bluetooth.onBLEConnectionStateChange(res => {  
                    // 该方法回调中可以用于处理连接意外断开等异常情况  
                    console.log(JSON.stringify(res));  
                    if (res.connected) {  
                        this.bleIsConnected = true;  
                        this.stopBluetoothDevicesDiscovery(); //关闭扫描功能  
                        this.bleButtonText = '设备已连接,点击断开连接';  
                        //连接后延迟1秒订阅特征  
                        setTimeout(()=> {  
                            console.log('去订阅特征');  
                            this.notifyBLECharacteristicValueChange();  
                            this.onBLECharacteristicValueChange();  
                        }, 1000);  
                    }else{  
                        this.bleIsNotify = false;  
                        this.bleIsConnected = false;  
                        this.bleIsReady = false;  
                        getApp().globalData.bleIsReady = false;  
                        this.bleButtonText = '点击搜索附近的蓝牙设备';  
                        this.closeBluetoothAdapter();  
                        toast('已经断开当前蓝牙连接');  
                    }  
                });  
            },  

            /**  
             * 监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。  
             */  
            onBLECharacteristicValueChange() {  
                // 必须在这里的回调才能获取  
                plus.bluetooth.onBLECharacteristicValueChange(characteristic => {  
                    console.log('收到空中数据: ' + (new Uint8Array(characteristic.value)).toString());  
                    this.rxCtrl.buffer.push(characteristic.value);  
                    if ( this.rxCtrl.isEnableRxTimer ){  
                        clearTimeout(this.rxCtrl.timerId);  
                        this.rxCtrl.timerId = setTimeout(this.bleRxMsgDeal, this.rxCtrl.rxIntervalMs);  
                    }else{  
                        this.rxCtrl.timerId = setTimeout(this.bleRxMsgDeal, this.rxCtrl.rxIntervalMs);  
                    }  
                    this.rxCtrl.isEnableRxTimer = true;  
                });  
            },  
            /**  
             * 订阅操作成功后需要设备主动更新特征值的 value,才会触发 uni.onBLECharacteristicValueChange 回调。  
             */  
            notifyBLECharacteristicValueChange() {  
                let deviceId = this.connectDevId;  
                let dataService = this.deviceDataServiceUUID;  
                let dataOutCharacteisicUUID = this.deviceDataOutCharacteisicUUID;  

                plus.bluetooth.notifyBLECharacteristicValueChange({  
                    state: true, // 启用 notify 功能  
                    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
                    deviceId: deviceId,  
                    // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取  
                    serviceId: dataService,  
                    // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取  
                    characteristicId: dataOutCharacteisicUUID,  
                    success: res => {  
                        this.bleIsReady = true;  
                        getApp().globalData.bleIsReady = true;  
                        console.log(JSON.stringify(res));  
                    },  

                    fail: e => {  
                        console.log('订阅通知失败' + e.errCode);  
                    }  
                });  
            },  

            /**  
             * 获取某个服务下的所有特征值  
             */  
            getBLEDeviceCharacteristics() {  
                console.log('获取所有特征值');  
                let deviceId = this.connectDevId;  
                let dataService = this.deviceDataServiceUUID;  
                //获取服务的所有特征值不能用plus.bluetooth或者会出错(例如,订阅的特征值更新一次会收到多个推送)  
                plus.bluetooth.getBLEDeviceCharacteristics({  
                    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
                    deviceId: deviceId,  
                    // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取  
                    serviceId: dataService,  
                    success: res => {  
                        console.log(JSON.stringify(res));  
                        console.log('获取特征值成功:' + res.errMsg);  
                    },  
                    fail: e => {  
                        console.log('获取特征值失败,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  

            writeBLECharacteristicValue(buffer){  
                console.log('发送');  
                let deviceId = this.connectDevId;  
                let dataService = this.deviceDataServiceUUID;  
                let dataInCharacteisicUUID = this.deviceDataInCharacterisicUUID;  

                //必须使用plus.bluetooth才能写入成功  
                plus.bluetooth.writeBLECharacteristicValue({  
                  // 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取  
                  deviceId: deviceId,  
                  // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取  
                  serviceId: dataService,  
                  // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取  
                  characteristicId: dataInCharacteisicUUID,  
                  // 这里的value是ArrayBuffer类型  
                  value: buffer,  
                  //调用成功  
                  success: res => {  
                    console.log(res);  
                    console.log('写特征成功');  
                  },  
                  //调用失败  
                  fail: e => {  
                      console.log(JSON.stringify(e));  
                  }  
                })  
            },  

            //蓝牙接收数据拼接处理  
            bleRxMsgDeal(){  
                var totalLength = 0;  
                for ( let i = 0; i < this.rxCtrl.buffer.length; i++ ){  
                    totalLength += this.rxCtrl.buffer[i].byteLength;  
                }  

                var totalBuffer = new ArrayBuffer(totalLength);  
                var totalData = new Uint8Array(totalBuffer);  
                totalLength = 0;  
                for ( let buff of this.rxCtrl.buffer){  
                    let data = new Uint8Array(buff);  
                    for ( let v of data ){  
                        totalData[totalLength++] = v;  
                    }  
                }  

                this.rxCtrl.buffer.length = 0; //清空接收缓存  
                console.log('拼接包数据:' + mlib.ab2hex(totalBuffer));  
                if ( ble.dealRecv(this.txCtrl.msgId, totalBuffer) ) {  
                    console.log('当前命令应答正确');  
                    this.txCtrl.isTxEmptr = true;  
                    this.bleLoaderMsgToBuffer();  
                }else{  
                    console.log('非当前命令应答');  
                }  
            },  

            /**  
             * 发送消息  
             */  
            bleTxMsg(){  
                var txLen = 20;  
                if ( this.txCtrl.residue < 20 ){  
                    txLen = this.txCtrl.residue;  
                }  

                if ( txLen > 0 ){  
                    let buffer = this.txCtrl.buffer.slice(this.txCtrl.offset, this.txCtrl.offset+txLen);  
                    this.txCtrl.offset += txLen;  
                    this.txCtrl.residue -= txLen;  
                    this.writeBLECharacteristicValue(buffer);         
                }  

                if ( this.txCtrl.residue == 0 ){  
                    if ( this.txCtrl.retry > 0 ){  
                        this.txCtrl.retry--;  
                        this.txCtrl.offset = 0;  
                        this.txCtrl.residue = this.txCtrl.buffer.byteLength;  

                        if ( this.txCtrl.isEnableTxTimer ){  
                            clearInterval(this.txCtrl.txTimerId)  
                            this.txCtrl.isEnableTxTimer = false;  
                        }  

                        if ( this.txCtrl.isEnableRetryTimer ){  
                            clearTimeout(this.txCtrl.retryTimerId)  
                            this.txCtrl.isEnableRetryTimer = false;  
                        }  

                        this.txCtrl.retryTimerId = setTimeout(()=>{  
                            console.log('再次重发');  
                            if ( this.txCtrl.isEnableTxTimer ){  
                                clearInterval(this.txCtrl.txTimerId)  
                            }  
                            this.txCtrl.txTimerId = setInterval(this.bleTxMsg, this.txCtrl.txIntervalMs);  
                            this.txCtrl.isEnableTxTimer = true;  
                        }, 2000);//间隔1秒重发报文   
                        this.txCtrl.isEnableRetryTimer = true;  
                    }else{  
                        console.log('发送超时');  
                        ble.sendTimeout(this.txCtrl.msgId);  
                        this.txCtrl.isTxEmptr = true;  
                        this.bleLoaderMsgToBuffer();  
                    }  
                }  
            },  

            /**  
             * 从消息发送队列中取出消息发送  
             * 设置发送间隔参考  
             * 测试发送10240个字节  
             * 50ms - 丢失0个字节  
             * 30ms - 丢失1个字节  
             * 20ms - 丢失1~10个字节  
             * 测试发送1024个字节  
             * 25ms - 偶尔会丢失1个字节33  
             */  
            bleLoaderMsgToBuffer(){  
                console.log('BLE发送消息队列缓存消息个数: ' +  this.ble_TxMsgQueue.length)  
                if ( !this.bleIsReady ){  
                    console.log('BLE未就绪'); return;  
                }else if ( !this.txCtrl.isTxEmptr ) {  
                    console.log('前一个消息还未发送完毕'); return;  
                }  

                //装载一个消息  
                if ( this.ble_TxMsgQueue.length != 0 ){  
                    console.log('装载报文');  
                    let sendMsg = this.ble_TxMsgQueue.shift();  
                    this.txCtrl.isTxEmptr = false;  
                    this.txCtrl.retry = 2;  
                    this.txCtrl.msgId = sendMsg.msgId;  
                    this.txCtrl.offset = 0;  
                    this.txCtrl.residue = sendMsg.msgContent.byteLength;  
                    this.txCtrl.buffer = sendMsg.msgContent;  

                    if ( this.txCtrl.isEnableTxTimer ){  
                        clearInterval(this.txCtrl.txTimerId)  
                    }  
                    this.txCtrl.txTimerId = setInterval(this.bleTxMsg, this.txCtrl.txIntervalMs);  
                    this.txCtrl.isEnableTxTimer = true;  

                }else{  
                    console.log('所有报文发送完毕');  
                    if ( this.txCtrl.isEnableTxTimer ){  
                        clearInterval(this.txCtrl.txTimerId)  
                        this.txCtrl.isEnableTxTimer = false;  
                    }  

                    if ( this.txCtrl.isEnableRetryTimer ){  
                        clearTimeout(this.txCtrl.retryTimerId)  
                        this.txCtrl.isEnableRetryTimer = false;  
                    }  
                }  
            }  
        },  

        onLoad(){  
            console.log('onLoad');  
            /**  
             * @param {Object} msgObj => {msgId: id, msgContent: value}  
             */  
            uni.$on('ble-tx', (msgObj) => {  
                console.log('消息压入发送队列')  
                this.ble_TxMsgQueue.push(msgObj);  
                this.bleLoaderMsgToBuffer();  
            });  
        },  

        onShow() {  
            console.log('onShow');  
        },  
    }  

    /**  
     * 判断初始化蓝牙状态  
     */  
    function initTypes(code, errMsg) {  
        switch (code) {  
            case 10000:  
                toast('未初始化蓝牙适配器');  
                break;  
            case 10001:  
                toast('未检测到蓝牙,请打开蓝牙重试!');  
                break;  
            case 10002:  
                toast('没有找到指定设备');  
                break;  
            case 10003:  
                toast('连接失败');  
                break;  
            case 10004:  
                toast('没有找到指定服务');  
                break;  
            case 10005:  
                toast('没有找到指定特征值');  
                break;  
            case 10006:  
                toast('当前连接已断开');  
                break;  
            case 10007:  
                toast('当前特征值不支持此操作');  
                break;  
            case 10008:  
                toast('其余所有系统上报的异常');  
                break;  
            case 10009:  
                toast('Android 系统特有,系统版本低于 4.3 不支持 BLE');  
                break;  
            default:  
                toast(errMsg);  
        }  
    }  

    /**  
     * 弹出框封装  
     */  
    function toast(content, showCancel = false) {  
        uni.showModal({  
            title: '提示',  
            content,  
            showCancel  
        });  
    }  

    // ArrayBuffer转16进度字符串示例  
    function ab2hex(buffer) {  
      var hexArr = Array.prototype.map.call(  
        new Uint8Array(buffer),  
        function (bit) {  
          return ('00' + bit.toString(16)).slice(-2)  
        }  
      )  
      return hexArr.join('')  
    }  
</script>  

操作步骤:

每次都会出现这个问题,必须重新打开应用才能再次正常连接蓝牙

预期结果:

能正常断开连接以及再次连接蓝牙设备

实际结果:

16:02:35.815 App Launch at App.vue:4
16:02:35.836 App Show at App.vue:7
16:02:37.720 onLoad at pages\main\bluetooth.vue:507
16:02:37.740 onShow at pages\main\bluetooth.vue:519
16:02:39.268 用户操作获取适配器 at pages\main\bluetooth.vue:88
16:02:39.289 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:119
16:02:39.311 {"discovering":false,"available":true} at pages\main\bluetooth.vue:99
16:02:39.330 成功开启蓝牙搜索... at pages\main\bluetooth.vue:147
16:02:40.554 选择设备ID:BA:03:63:1B:A2:B5 at pages\main\bluetooth.vue:67
16:02:40.574 创建BLE连接 at pages\main\bluetooth.vue:219
16:02:40.823 [Object] {"errMsg":"createBLEConnection:ok"} at pages\main\bluetooth.vue:224
16:02:40.844 {"deviceId":"BA:03:63:1B:A2:B5","connected":true} at pages\main\bluetooth.vue:256
16:02:40.864 [Object] {"code":0,"message":"ok"} at pages\main\bluetooth.vue:172
16:02:41.819 去订阅特征 at pages\main\bluetooth.vue:263
16:02:41.840 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:315
16:02:42.191 用户操作断开蓝牙连接 at pages\main\bluetooth.vue:82
16:02:42.212 断开BLE连接:BA:03:63:1B:A2:B5 at pages\main\bluetooth.vue:237
16:02:42.233 [Object] {"errMsg":"closeBLEConnection:ok"} at pages\main\bluetooth.vue:241
16:02:42.253 {"deviceId":"BA:03:63:1B:A2:B5","connected":false} at pages\main\bluetooth.vue:256
16:02:42.273 断开蓝牙模块成功 at pages\main\bluetooth.vue:136
16:02:45.605 用户操作获取适配器 at pages\main\bluetooth.vue:88
16:02:45.625 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:119
16:02:45.646 {"discovering":false,"available":true} at pages\main\bluetooth.vue:99
16:02:45.670 成功开启蓝牙搜索... at pages\main\bluetooth.vue:147
16:02:48.217 选择设备ID:BA:03:63:1B:A2:B5 at pages\main\bluetooth.vue:67
16:02:48.237 创建BLE连接 at pages\main\bluetooth.vue:219
16:02:48.444 [Object] {"errMsg":"createBLEConnection:ok"} at pages\main\bluetooth.vue:224
16:02:48.469 {"deviceId":"BA:03:63:1B:A2:B5","connected":true} at pages\main\bluetooth.vue:256
16:02:48.505 {"deviceId":"BA:03:63:1B:A2:B5","connected":true} at pages\main\bluetooth.vue:256
16:02:48.526 [Object] {"code":0,"message":"ok"} at pages\main\bluetooth.vue:172
16:02:48.546 [Object] {"code":0,"message":"ok"} at pages\main\bluetooth.vue:172
16:02:49.477 去订阅特征 at pages\main\bluetooth.vue:263
16:02:49.498 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:315
16:02:49.518 去订阅特征 at pages\main\bluetooth.vue:263
16:02:49.539 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:315
16:02:50.306 用户操作断开蓝牙连接 at pages\main\bluetooth.vue:82
16:02:50.327 断开BLE连接:BA:03:63:1B:A2:B5 at pages\main\bluetooth.vue:237
16:02:50.348 [Object] {"errMsg":"closeBLEConnection:ok"} at pages\main\bluetooth.vue:241
16:02:50.369 {"deviceId":"BA:03:63:1B:A2:B5","connected":false} at pages\main\bluetooth.vue:256
16:02:50.389 {"deviceId":"BA:03:63:1B:A2:B5","connected":false} at pages\main\bluetooth.vue:256
16:02:50.410 断开蓝牙模块成功 at pages\main\bluetooth.vue:136
16:02:50.432 断开蓝牙模块成功 at pages\main\bluetooth.vue:136
16:02:53.062 用户操作获取适配器 at pages\main\bluetooth.vue:88
16:02:53.082 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:119
16:02:53.102 {"discovering":false,"available":true} at pages\main\bluetooth.vue:99
16:02:53.123 成功开启蓝牙搜索... at pages\main\bluetooth.vue:147
16:02:54.538 选择设备ID:BA:03:63:1B:A2:B5 at pages\main\bluetooth.vue:67
16:02:54.553 创建BLE连接 at pages\main\bluetooth.vue:219
16:02:55.382 [Object] {"errMsg":"createBLEConnection:ok"} at pages\main\bluetooth.vue:224
16:02:55.410 {"deviceId":"BA:03:63:1B:A2:B5","connected":true} at pages\main\bluetooth.vue:256
16:02:55.423 {"deviceId":"BA:03:63:1B:A2:B5","connected":true} at pages\main\bluetooth.vue:256
16:02:55.443 {"deviceId":"BA:03:63:1B:A2:B5","connected":true} at pages\main\bluetooth.vue:256
16:02:55.464 [Object] {"code":0,"message":"ok"} at pages\main\bluetooth.vue:172
16:02:55.485 [Object] {"code":0,"message":"ok"} at pages\main\bluetooth.vue:172
16:02:55.505 [Object] {"code":0,"message":"ok"} at pages\main\bluetooth.vue:172
16:02:56.397 去订阅特征 at pages\main\bluetooth.vue:263
16:02:56.418 去订阅特征 at pages\main\bluetooth.vue:263
16:02:56.439 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:315
16:02:56.459 去订阅特征 at pages\main\bluetooth.vue:263
16:02:56.499 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:315
16:02:56.512 {"code":0,"message":"ok"} at pages\main\bluetooth.vue:315

bug描述:

使用低功耗蓝牙时,先使用uni.createBLEConnection创建连接后,再使用uni.closeBLEConnection断开连接,重复连接断开这两个步骤。每多操作一次就会导致再次创建连接时plus.bluetooth.onBLEConnectionStateChange会被多次回调,从现象分析应该是uni.closeBLEConnection没有起作用

2020-05-19 16:06 负责人:DCloud_Android_zl 分享
已邀请:

最佳回复

DCloud_UNI_GSQ

DCloud_UNI_GSQ

HBuilderX alpha 2.9.0+ 已修复

其他版本临时解决方案:改用 plus.bluetooth.onBluetoothDeviceFound 等接口

5***@qq.com

5***@qq.com

如果程序里面要用到两个不同的蓝牙设置会出问题,官方什么时候修复,2.5.1之前是可以的,更新了几个版本了也没有修复这个问题

DCloud_UNI_GSQ

DCloud_UNI_GSQ

只有安卓遇到此问题吗?

  • 2***@qq.com

    你好,uni-app是手机端都有这个问题的困扰,多次监听无法移除,小程序不存在这个问题。不过iOS端用plus的方法不存在多次监听的情况。我看小程序蓝牙模块对应的监听事件都有移除监听事件的方法,咱uni-app是设计这里时不需要移除监听,还是说还没更新到。

    2020-06-11 16:46

xuewenhui

xuewenhui (作者)

只用安卓

DCloud_Android_zl

DCloud_Android_zl

我看你代码是通过uni.createBLEConnection创建连接,你试试换成5+的会不会还有类似的问题。

  • 2***@qq.com

    他应该不是连接的问题,是蓝牙这里所有的监听事件开启之后没有移除的方法,所以导致进入几次之后,就会有个多个监听事件存在了。我现在也在用蓝牙这里,因为多次监听困扰很久了。不过@heesim这位朋友的思路可以试试。@官方,希望咱官方能更细一下方法吧,我看小程序的API中已经有专门对应的移除监听事件的方法了。

    2020-06-11 16:44

  • 2***@qq.com

    回复 2***@qq.com: 修改:更细为更新。

    2020-06-11 16:44

3***@qq.com

3***@qq.com - 前端开发

我有同样的问题,我的问题是 链接一次 创建了一次实例。调用断开的方法,根本不起作用,下次链接的时候,又创建了一个实例, 例如A页面创建了一个实例,监听蓝牙的变化,退出A页面,并且关闭了已连接的蓝牙模块。 在B页面或者还是在A页面又链接蓝牙,创建了一个实例,监听蓝牙数据变化。 这个时候出问题了,两个监听都在!!! A的监听根本没有断开, 楼主问题是不是一样?

  • heesim

    看我楼下回复,我是这个解决方案。uniapp的reluach并不会销毁监听器,需要手动销毁。

    2020-06-06 11:05

heesim

heesim - zsp

你这个问题并不是启动了多个实例把。你每次创建连接成功,就会启动一个关于连接状态的监听,每多操作一次就会多创建一个监听器。所以导致了每操作一次打印多一行代码出来。建议你把onBLEConnectionStateChange移步到app.vue中,应用初始化,蓝牙适配器初始化的时候在创建一个全局的监听。然后通过uni.$emit发送蓝牙状态到各个页面的uni.$on监听器上。 (因为官方文档并没有关闭onBLEConnectionStateChange的接口,只能手动封装一层这样子的监听器,页面卸载的时候可以通过uni.$off卸载相关监听)

  • xuewenhui (作者)

    谢谢,确实是这个原因

    2020-06-10 13:48

1***@qq.com

1***@qq.com - 90后it

我也是多次连接之后会出现这种情况

该问题目前已经被锁定, 无法添加新回复