2***@qq.com
2***@qq.com
  • 发布:2023-03-16 16:38
  • 更新:2024-01-10 11:31
  • 阅读:806

【报Bug】APP在运行过程中,多次执行uni.createBLEConnection后,uni.createBLEConnection功能异常,无法连接设备

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

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

HBuilderX类型: 正式

HBuilderX版本号: 3.7.3

手机系统: Android

手机系统版本号: Android 11

手机厂商: 小米

手机机型: 红米note10 pro

页面类型: vue

vue版本: vue2

打包方式: 云端

项目创建方式: HBuilderX

示例代码:
<template>  
    <view>  
        <page-head :title="title"></page-head>  
        <view class="uni-padding-wrap uni-common-mt">  
            <view>  
                本蓝牙协议只支持低功耗蓝牙协议ble。如果想连接非ble蓝牙设备,请在社区搜索 Native.js 蓝牙。  
            </view>  
            <view class="uni-btn-v">  
                <button type="primary" :disabled="disabled[0]" @click="openBluetoothAdapter">  
                    初始化蓝牙模块  
                </button>  
                <view v-if="!adapterState.available">  
                    {{ '蓝牙适配器不可用,请初始化蓝牙模块' }}  
                </view>  
                <button type="primary" :loading="searchLoad" :disabled="disabled[1]"  
                    @click="startBluetoothDevicesDiscovery">  
                    开始搜索蓝牙设备  
                </button>  
                <view class="uni-scroll_box">  
                    <view class="uni-title">  
                        已经发现{{ devices.length }}台设备  
                    </view>  
                    <view class="uni-list-box" v-for="(item, index) in devices" :key="index" @click="tapQuery(item)">  
                        <view>  
                            <view class="uni-list_name">{{ item.name || item.localName }}</view>  
                            <view class="uni-list_item">信号强度:{{ item.RSSI }}dBm</view>  
                            <view class="uni-list_item">UUID:{{ item.deviceId }}</view>  
                        </view>  
                    </view>  
                </view>  

                <button type="primary" :disabled="disabled[2]" @click="stopBluetoothDevicesDiscovery(false)">  
                    停止搜索蓝牙设备  
                </button>  
                <button type="primary" :loading="newDeviceLoad" :disabled="disabled[3]" @click="queryDevices">  
                    选择设备  
                </button>  
                <view v-if="equipment.length > 0">  
                    {{  
                        (connected ? '已连接设备' : '已选择设备') +  
                            ' : ' +  
                            equipment[0].name +  
                            ' (' +  
                            equipment[0].deviceId +  
                            ')'  
                    }}  
                </view>  
                <button type="primary" :disabled="disabled[4]" @click="createBLEConnection">  
                    连接蓝牙设备  
                </button>  
                <button type="primary" :disabled="disabled[5]" @click="getBLEDeviceServices">  
                    选择设备服务  
                </button>  
                <view v-if="servicesData.length > 0">已选服务uuid:{{ servicesData[0].uuid }}</view>  
                <button type="primary" :disabled="disabled[6]" @click="getBLEDeviceCharacteristics">  
                    获取服务的特征值  
                </button>  
                <view v-if="characteristicsData.length > 0">  
                    <view class="uni-list_name">uuid:{{ characteristicsData[0].uuid }}</view>  
                    <view class="uni-list_item">  
                        是否支持 read 操作:{{ characteristicsData[0].properties.read }}  
                    </view>  
                    <view class="uni-list_item">  
                        是否支持 write 操作:{{ characteristicsData[0].properties.write }}  
                    </view>  
                    <view class="uni-list_item">  
                        是否支持 notify 操作:{{ characteristicsData[0].properties.notify }}  
                    </view>  
                    <view class="uni-list_item">  
                        是否支持 indicate 操作:{{ characteristicsData[0].properties.indicate }}  
                    </view>  
                </view>  
                <!-- <button type="primary" :disabled="disabled[7]" @click="readBLECharacteristicValue">  
                    读取特征值数据  
                </button>  
                <view v-if="valueChangeData.serviceId">  
                    <view class="list-name">  
                        特征值最新的值:{{ valueChangeData.value || '还没有最新值' }}  
                    </view>  
                </view> -->  
                <!-- <button type="primary" :disabled="disabled[8]" @click="w">写入特征值数据</button> -->  
                <button type="primary" :disabled="disabled[9]" @click="closeBLEConnection">  
                    断开蓝牙设备  
                </button>  
                <button type="primary" :disabled="disabled[10]" @click="closeBluetoothAdapter">  
                    关闭蓝牙模块  
                </button>  

                <view class="cc">{{cResult}}</view>  
            </view>  
        </view>  
        <!-- 遮罩 -->  
        <view v-if="maskShow" class="uni-mask" @touchmove.stop.prevent="moveHandle" @click="maskclose">  
            <scroll-view class="uni-scroll_box" scroll-y @touchmove.stop.prevent="moveHandle" @click.stop="moveHandle">  
                <view class="uni-title">  
                    已经发现{{ list.length }}{{ showMaskType === 'device' ? '台设备' : '个服务' }}:  
                </view>  
                <view class="uni-list-box" v-for="(item, index) in list" :key="index" @click="tapQuery(item)">  
                    <view v-if="showMaskType === 'device'">  
                        <view class="uni-list_name">{{ item.name || item.localName }}</view>  
                        <view class="uni-list_item">信号强度:{{ item.RSSI }}dBm</view>  
                        <view class="uni-list_item">UUID:{{ item.deviceId }}</view>  
                        <!-- <view class="list-item" v-if="showMaskType === 'device'">  
                            Service数量:{{ item.advertisServiceUUIDs.length }}  
                        </view> -->  
                    </view>  
                    <view v-if="showMaskType === 'service'">  
                        <view class="uni-list_item" style="line-height:2.2;">  
                            UUID: {{ item.uuid }}  
                            <text v-if="showMaskType === 'service'">  
                                {{ item.isPrimary ? '(主服务)' : '' }}  
                            </text>  
                        </view>  
                    </view>  
                    <view v-if="showMaskType === 'characteristics'">  
                        <view class="uni-list_name">uuid:{{ item.uuid }}</view>  
                        <view class="uni-list_item">是否支持 read 操作:{{ item.properties.read }}</view>  
                        <view class="uni-list_item">  
                            是否支持 write 操作:{{ item.properties.write }}  
                        </view>  
                        <view class="uni-list_item">  
                            是否支持 notify 操作:{{ item.properties.notify }}  
                        </view>  
                        <view class="uni-list_item">  
                            是否支持 indicate 操作:{{ item.properties.indicate }}  
                        </view>  
                    </view>  
                </view>  
            </scroll-view>  
        </view>  
    </view>  
</template>  
<script>  
    export default {  
        data() {  
            return {  
                title: 'bluetooth',  
                disabled: [false, true, true, true, true, true, true, true, true, true, true],  
                newDeviceLoad: false,  
                searchLoad: false,  
                maskShow: false,  
                equipment: [],  
                adapterState: {  
                    discovering: false,  
                    available: false  
                },  
                connected: false,  
                showMaskType: 'device',  
                servicesData: [],  
                characteristicsData: [],  
                valueChangeData: {},  
                isStop: true,  
                list: [],  
                devices: [],  
                cResult:'',  
            };  
        },  
        onLoad() {  
            this.onBLEConnectionStateChange();  
        },  
        methods: {  
            moveHandle() {},  
            /**  
             * 关闭遮罩  
             */  
            maskclose() {  
                this.maskShow = false;  
            },  
            /**  
             * 选择设备  
             */  
            queryDevices() {  
                // this.newDeviceLoad = true;  
                this.showMaskType = 'device';  
                this.maskShow = true;  
            },  
            tapQuery(item) {  
                if (this.showMaskType === 'device') {  
                    this.$set(this.disabled, 4, false);  
                    if (this.equipment.length > 0) {  
                        this.equipment[0] = item;  
                    } else {  
                        this.equipment.push(item);  
                    }  

                    this.newDeviceLoad = false;  
                }  
                if (this.showMaskType === 'service') {  
                    this.$set(this.disabled, 6, false);  
                    if (this.servicesData.length > 0) {  
                        this.servicesData[0] = item;  
                    } else {  
                        this.servicesData.push(item);  
                    }  
                }  
                if (this.showMaskType === 'characteristics') {  
                    this.$set(this.disabled, 7, false);  
                    if (this.characteristicsData.length > 0) {  
                        this.characteristicsData[0] = item;  
                    } else {  
                        this.characteristicsData.push(item);  
                    }  
                }  
                this.maskShow = false;  
            },  
            /**  
             * 初始化蓝牙设备  
             */  
            openBluetoothAdapter() {  
                uni.openBluetoothAdapter({  
                    success: e => {  
                        console.log('初始化蓝牙成功:' + e.errMsg);  
                        console.log(JSON.stringify(e));  
                        this.isStop = false;  
                        this.$set(this.disabled, 0, true);  
                        this.$set(this.disabled, 1, false);  
                        this.$set(this.disabled, 10, false);  
                        this.getBluetoothAdapterState();  
                    },  
                    fail: e => {  
                        console.log(e)  
                        console.log('初始化蓝牙失败,错误码:' + (e.errCode || e.errMsg));  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode, e.errMsg);  
                        }  
                    }  
                });  
            },  
            /**  
             * 开始搜索蓝牙设备  
             */  
            startBluetoothDevicesDiscovery() {  
                uni.startBluetoothDevicesDiscovery({  
                    success: e => {  
                        console.log('开始搜索蓝牙设备:' + e.errMsg);  
                        this.searchLoad = true;  
                        this.$set(this.disabled, 1, true);  
                        this.$set(this.disabled, 2, false);  
                        this.$set(this.disabled, 3, false);  
                        this.onBluetoothDeviceFound();  
                    },  
                    fail: e => {  
                        console.log('搜索蓝牙设备失败,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  
            /**  
             * 停止搜索蓝牙设备  
             */  
            stopBluetoothDevicesDiscovery(types) {  
                uni.stopBluetoothDevicesDiscovery({  
                    success: e => {  
                        console.log('停止搜索蓝牙设备:' + e.errMsg);  
                        if (types) {  
                            this.$set(this.disabled, 1, true);  
                        } else {  
                            this.$set(this.disabled, 1, false);  
                        }  
                        this.$set(this.disabled, 2, true);  
                        // this.$set(this.disabled, 3, true);  
                        this.searchLoad = false;  
                    },  
                    fail: e => {  
                        console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  
            /**  
             * 发现外围设备  
             */  
            onBluetoothDeviceFound() {  
                uni.onBluetoothDeviceFound(devices => {  
                    console.log('开始监听寻找到新设备的事件');  
                    // this.$set(this.disabled, 3, false);  
                    this.getBluetoothDevices();  
                });  
            },  
            /**  
             * 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。  
             */  
            getBluetoothDevices() {  
                uni.getBluetoothDevices({  
                    success: res => {  
                        this.newDeviceLoad = false;  
                        console.log('获取蓝牙设备成功:' + res.errMsg);  
                        // console.log(JSON.stringify(res))  
                        this.list = res.devices;  
                        this.devices = res.devices;  
                    },  
                    fail: e => {  
                        console.log('获取蓝牙设备错误,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  
            /**  
             * 获取本机蓝牙适配器状态  
             */  
            getBluetoothAdapterState() {  
                console.log('--->');  
                uni.getBluetoothAdapterState({  
                    success: res => {  
                        console.log(JSON.stringify(res));  
                        this.adapterState = res;  
                    },  
                    fail: e => {  
                        console.log('获取本机蓝牙适配器状态失败,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  
            /**  
             * 连接低功耗蓝牙  
             */  
            createBLEConnection() {  
                let deviceId = this.equipment[0].deviceId;  
                uni.showToast({  
                    title: '连接蓝牙...',  
                    icon: 'loading',  
                    duration: 99999  
                });  
                uni.createBLEConnection({  
                    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
                    deviceId,  
                    success: res => {  
                        console.log(res);  
                        console.log('连接蓝牙成功:' + res.errMsg);  
                        // 连接设备后断开搜索 并且不能搜索设备  
                        this.stopBluetoothDevicesDiscovery(true);  
                        uni.hideToast();  
                        uni.showToast({  
                            title: '连接成功',  
                            icon: 'success',  
                            duration: 2000  
                        });  
                        this.$set(this.disabled, 3, true);  
                        this.$set(this.disabled, 4, true);  
                        this.$set(this.disabled, 5, false);  
                        this.$set(this.disabled, 9, false);  
                        this.connected = true;  
                    },  
                    fail: e => {  
                        console.log('连接低功耗蓝牙失败,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  
            /**  
             * 断开与低功耗蓝牙设备的连接  
             */  
            closeBLEConnection() {  

                this.manualDisconnect = true;  
                let deviceId = this.equipment[0].deviceId;  
                uni.closeBLEConnection({  
                    deviceId,  
                    success: res => {  
                        console.log(res);  
                        console.log('断开低功耗蓝牙成功:' + res.errMsg);  
                        this.$set(this.disabled, 1, false);  
                        this.$set(this.disabled, 3, true);  
                        this.$set(this.disabled, 4, true);  
                        this.$set(this.disabled, 5, true);  
                        this.$set(this.disabled, 6, true);  
                        this.$set(this.disabled, 7, true);  
                        this.$set(this.disabled, 8, true);  
                        this.$set(this.disabled, 9, true);  
                        // this.equipment = [];  
                        this.servicesData = [];  
                        this.characteristicsData = [];  
                    },  
                    fail: e => {  
                        console.log('断开低功耗蓝牙成功,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  
            /**  
             * 获取所有服务  
             */  
            getBLEDeviceServices() {  
                let deviceId = this.equipment[0].deviceId;  
                console.log('获取所有服务的 uuid:' + deviceId);  

                uni.getBLEDeviceServices({  
                    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
                    deviceId,  
                    success: res => {  
                        console.log(JSON.stringify(res.services));  
                        console.log('获取设备服务成功:' + res.errMsg);  
                        this.$set(this.disabled, 7, true);  
                        this.$set(this.disabled, 8, true);  
                        this.showMaskType = 'service';  
                        this.list = res.services;  

                        this.characteristicsData = [];  
                        if (this.list.length <= 0) {  
                            toast('获取服务失败,请重试!');  
                            return;  
                        }  
                        this.maskShow = true;  
                    },  
                    fail: e => {  
                        console.log('获取设备服务失败,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  
            /**  
             * 获取某个服务下的所有特征值  
             */  
            getBLEDeviceCharacteristics() {  
                let deviceId = this.equipment[0].deviceId;  
                let serviceId = this.servicesData[0].uuid;  
                console.log(deviceId);  
                console.log(serviceId);  
                uni.getBLEDeviceCharacteristics({  
                    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
                    deviceId,  
                    // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取  
                    serviceId,  
                    success: res => {  
                        console.log(JSON.stringify(res));  
                        console.log('获取特征值成功:' + res.errMsg);  
                        this.$set(this.disabled, 7, true);  
                        this.valueChangeData = {};  
                        this.showMaskType = 'characteristics';  
                        this.list = res.characteristics;  
                        if (this.list.length <= 0) {  
                            toast('获取特征值失败,请重试!');  
                            return;  
                        }  
                        this.maskShow = true;  
                    },  
                    fail: e => {  
                        console.log('获取特征值失败,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
            },  
            /**  
             * 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等  
             */  
            onBLEConnectionStateChange() {  
                uni.onBLEConnectionStateChange(res => {  
                    // 该方法回调中可以用于处理连接意外断开等异常情况  
                    console.log(`蓝牙连接状态 -------------------------->`);  
                    console.log(JSON.stringify(res));  

                    this.notifyConnectState = res.connected;  
                    if (!res.connected) {  

                        if (this.isStop) return;  
                        console.log('断开低功耗蓝牙成功:');  
                        this.$set(this.disabled, 1, false);  
                        this.$set(this.disabled, 3, true);  
                        this.$set(this.disabled, 4, true);  
                        this.$set(this.disabled, 5, true);  
                        this.$set(this.disabled, 6, true);  
                        this.$set(this.disabled, 7, true);  
                        this.$set(this.disabled, 8, true);  
                        this.$set(this.disabled, 9, true);  
                        this.searchLoad = false;  
                        // this.equipment = [];  
                        this.servicesData = [];  
                        this.characteristicsData = [];  
                        this.valueChangeData = {};  
                        toast('已经断开当前蓝牙连接');  

                        if (this.manualDisconnect) {  
                            this.manualDisconnect = false;  
                        } else {  
                            // 开启自动连接  
                            this.startAutoConnect();  
                        }  

                    } else {  
                        // 连接成功的话,则获取ID  
                        this.cDeviceId = res.deviceId;  
                        this.stopAutoConect();  

                    }  
                });  
            },  
            /**  
             * 读取低功耗蓝牙设备的特征值的二进制数据值。注意:必须设备的特征值支持 read 才可以成功调用  
             */  
            readBLECharacteristicValue() {  
                let deviceId = this.equipment[0].deviceId;  
                let serviceId = this.servicesData[0].uuid;  
                let characteristicId = this.characteristicsData[0].uuid;  
                console.log(deviceId);  
                console.log(serviceId);  
                console.log(characteristicId);  
                uni.readBLECharacteristicValue({  
                    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
                    deviceId,  
                    // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取  
                    serviceId,  
                    // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取  
                    characteristicId,  
                    success: res => {  
                        console.log('读取设备数据值成功');  
                        console.log(JSON.stringify(res));  
                        this.notifyBLECharacteristicValueChange();  
                    },  
                    fail(e) {  
                        console.log('读取设备数据值失败,错误码:' + e.errCode);  
                        if (e.errCode !== 0) {  
                            initTypes(e.errCode);  
                        }  
                    }  
                });  
                this.onBLECharacteristicValueChange();  
            },  
            /**  
             * 监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。  
             */  
            onBLECharacteristicValueChange() {  
                // 必须在这里的回调才能获取  
                uni.onBLECharacteristicValueChange(characteristic => {  
                    console.log('监听低功耗蓝牙设备的特征值变化事件成功');  
                    console.log(JSON.stringify(characteristic));  
                    this.valueChangeData = characteristic;  
                });  
            },  
            /**  
             * 订阅操作成功后需要设备主动更新特征值的 value,才会触发 uni.onBLECharacteristicValueChange 回调。  
             */  
            notifyBLECharacteristicValueChange() {  
                let deviceId = this.equipment[0].deviceId;  
                let serviceId = this.servicesData[0].uuid;  
                let characteristicId = this.characteristicsData[0].uuid;  
                let notify = this.characteristicsData[0].properties.notify;  
                console.log(deviceId);  
                console.log(serviceId);  
                console.log(characteristicId);  
                console.log(notify);  
                uni.notifyBLECharacteristicValueChange({  
                    state: true, // 启用 notify 功能  
                    // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接  
                    deviceId,  
                    // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取  
                    serviceId,  
                    // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取  
                    characteristicId,  
                    success(res) {  
                        console.log('notifyBLECharacteristicValueChange success:' + res.errMsg);  
                        console.log(JSON.stringify(res));  
                    }  
                });  
            },  
            /**  
             *  断开蓝牙模块  
             */  
            closeBluetoothAdapter(OBJECT) {  
                uni.closeBluetoothAdapter({  
                    success: res => {  
                        console.log('断开蓝牙模块成功');  
                        this.isStop = true;  
                        this.$set(this.disabled, 0, false);  
                        this.$set(this.disabled, 1, true);  
                        this.$set(this.disabled, 2, true);  
                        this.$set(this.disabled, 3, true);  
                        this.$set(this.disabled, 4, true);  
                        this.$set(this.disabled, 5, true);  
                        this.$set(this.disabled, 6, true);  
                        this.$set(this.disabled, 7, true);  
                        this.$set(this.disabled, 8, true);  
                        this.$set(this.disabled, 9, true);  
                        this.$set(this.disabled, 10, true);  
                        // this.equipment = [];  
                        this.servicesData = [];  
                        this.characteristicsData = [];  
                        this.valueChangeData = {};  
                        this.adapterState = [];  
                        this.searchLoad = false;  
                        toast('断开蓝牙模块');  
                    }  
                });  
            },  

            // 开启自动连接  
            startAutoConnect() {  

                if (this.autoConnectState) {  
                    return;  
                }  

                this.autoConnectState = true;  
                this.autoConnectCount = 0;  

                this.autoTimer = setTimeout(() => {  
                    this.onceConnect();  
                }, 3000);  
            },  

            delayAutoConnect() {  
                if (!this.autoConnectState) {  
                    return;  
                }  

                if(this.delayTimer) {  
                    clearTimeout(this.delayTimer);  
                    this.delayTimer = null;  
                }  

                this.delayTimer = setTimeout(() => {  
                    if (!this.notifyConnectState) {  
                        this.onceConnect();  
                    }  
                }, 5000);  
            },  

            onceConnect() {  
                this.autoConnectCount++;  
                console.log('------ auto connect device num:' + this.autoConnectCount)  
                uni.createBLEConnection({  
                    deviceId: this.cDeviceId,  
                    timeout: 15000,  
                    success: res => {  
                        console.log(res);  
                        console.log('连接蓝牙成功:' + res.errMsg);  
                        // 连接设备后断开搜索 并且不能搜索设备  
                        this.stopBluetoothDevicesDiscovery(true);  
                        uni.hideToast();  
                        uni.showToast({  
                            title: '连接成功',  
                            icon: 'success',  
                            duration: 2000  
                        });  
                        this.$set(this.disabled, 3, true);  
                        this.$set(this.disabled, 4, true);  
                        this.$set(this.disabled, 5, false);  
                        this.$set(this.disabled, 9, false);  
                        this.connected = true;  
                        this.delayAutoConnect();  
                    },  
                    fail: e => {  
                        console.log('连接低功耗蓝牙失败,错误码:' + e.errCode);  
                        console.log(e)  
                        if (e.errCode !== 0) {  
                            // this.cResult += initTypes(e.errCode,'','return');  
                            this.cResult += '次数:' + this.autoConnectCount + ' ' + JSON.stringify(e) + '\n';  
                        }  

                        this.delayAutoConnect();  
                    }  
                });  
            },  

            stopAutoConect() {  
                this.autoConnectState = false;  
                this.autoConnectCount = 0;  
                if (this.autoTimer) {  
                    clearInterval(this.autoTimer);  
                    this.autoTimer = null;  
                }  
            }  
        }  
    };  

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

        if(returnMsg) {  
            return msg;  
        }  
        toast(msg);  
    }  

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

操作步骤:
  1. 下载压缩包,导入项目。将手机连接电脑,将手机配置调整成可用于真机调试的程度。准备一个可连接的蓝牙设备。 开始真机调试(可使用Hbuilerx的标准基座进行真机调试)。
  2. 打开手机蓝牙;
  3. 点击“初始化蓝牙模块”按钮;
  4. 点击“开始搜索蓝牙设备”按钮;
  5. 在确定搜索到用于测试的蓝牙设备后,点击”选择设备“按钮,选择该设备;
  6. 点击”连接蓝牙设备“按钮,确定设备已经连接成功;
  7. 确定设备已连接后,将蓝牙设备关闭,随后APP会有连接断开的提示弹窗显示,关闭连接断开的提示弹窗;
  8. 将手机放置不动,此时代码会开始尝试自动连接该蓝牙设备。通过hbuilerX控制台能查看日志。 最开始执行时 ” ------ auto connect device num“与” 连接低功耗蓝牙失败,错误码:10012 “ 两个日志显示的时间会相差15秒。
    9 在手机放置了20分钟或更多时间后,” ------ auto connect device num“与” 连接低功耗蓝牙失败,错误码:10012 “ 两个日志显示的时间仅会相差十几毫秒左右。此时功能异常,开启之前关闭的蓝牙设备,观察APP是否能连接上该蓝牙设备。

预期结果:

蓝牙设备开启后,APP执行连接操作响应: {"errMsg":"createBLEConnection:ok"} ; 而后触发uni.onBLEConnectionStateChange监听,提示连接成功。

实际结果:

蓝牙设备开启后,APP执行连接操作响应:{"errMsg":"createBLEConnection:fail operate time out","errCode":10012,"code":10012} ,蓝牙设备未连接成功

bug描述:

使用低功耗蓝牙连接一个蓝牙设备后,保存该设备的deviceId。在蓝牙设备关闭后,APP会触发蓝牙设备断开事件,此时让APP每隔5秒尝试直接通过deviceId连接一次设备,uni.createBLEConnection设置的超时时间为15秒。

在开始的一段时间内,执行uni.createBLEConnection到触发其回调的时间刚好是15秒,连接方法执行正常,且响应的回调为:

{"errMsg":"createBLEConnection:fail operate time out","errCode":10012,"code":10012} 

过了一段时间后,执行uni.createBLEConnection到触发其回调的时间则在50毫秒内,远低于正常值,响应回调为:

{"errMsg":"createBLEConnection:fail operate time out","errCode":10012,"code":10012}

此时uni.createBLEConnection的功能已经失效了。如将蓝牙设备打开,执行uni.createBLEConnection仍然是连接不上的。

测试过程中手机是常亮的状态,且APP一直在前台显示。一般在执行90次左右后出现。

其他:

  • 此时需要开关系统蓝牙或重启APP功能才恢复正常。
  • 存在uni.startBluetoothDevicesDiscovery功能异常的情况,此时进行搜索操作无法搜索到蓝牙设备。不是一定触发,有一次在手机放置超过半小时后出现了这个现象。
2023-03-16 16:38 负责人:DCloud_Android_zl 分享
已邀请:
胖小虎

胖小虎

遇见同样的问题,Android为华为Mate20。如果把蓝牙连接超时不设置,默认30s会产生连接超时,间隔2s后再次连接。这样设计,大概把手机放那2~3个小时,就会出现createBLEConnection一直失败,只有重启APP才可恢复。

如果把连接超时设置为15s左右,在1~2次重试连接后,超时事件会从15s自动变化到6~7s左右。然后就开始出现一样的无法连接的问题。

调试过程中,更新JS代码自动重新加载页面(没有重启APP),这时如果把Adapter重新初始化后调用createBLEConnection,也会很容易复现以上问题。所以一直怀疑是不是存在后台多个连接造成的问题。

在每次createBLEConnection前去做一次closeBLEConnection对这个问题有缓解(仅缓解),但最终还是过不了长时间测试。

DCloud_Android_zl

DCloud_Android_zl

我们这边在测试的时候发现蓝牙设备在断开重启之后,设备的address可能会变,你看一下你那边的蓝牙设备是不是也是这种情况

  • 2***@qq.com (作者)

    不是的,设备的deviceId没有变化。出现该现象时不仅是之前断开的设备不能连接,其他所有的蓝牙设备都无法连接成功。 测试时一般自动连接50多次后就会出现这个情况,之前放在连接100多次后有出现过连搜索蓝牙设备API都失效的情况。且红米的手机可能多个型号都存在这个问题, 这边测试使用红米note10pro、红米6A都复现了。

    2023-04-07 16:55

  • DCloud_Android_zl

    回复 2***@qq.com: 我这边目前没有这样的设备,方不方便提供一个设备让我们调试一下

    2023-04-07 17:30

  • 2***@qq.com (作者)

    回复 DCloud_Android_zl: 小米的手机可能都能测试出这个问题。这边最开始就是小米12测出这个现象的。项目APP蓝牙功能异常后,BLE调试助手也运行异常了,无法搜索到任何设备,而系统蓝牙则能正常搜索设备。 且出现这个现象的场景与APP运行期间调用过的uni.createBLEConnection总次数有关系。测试每自动连接10次左右再让其连接成功,然后再关闭蓝牙设备断开连接, 如果重复五六次后,也出现了蓝牙异常情况的情况。

    2023-04-07 17:54

  • DCloud_Android_zl

    回复 2***@qq.com: 我这边目前没有这样的设备,方不方便提供一个蓝牙设备让我们调试一下

    2023-04-07 21:37

  • 2***@qq.com (作者)

    回复 DCloud_Android_zl: 这个对蓝牙设备没要求的,只要该设备支持低功耗蓝牙,能被搜索并连接到就行。本质是要让APP执行蓝牙连接次数超过一个数,这个数可能是50,也可以是90,就会导致APP蓝牙功能异常。 我这使用过小米的手环也能复现。使用设备进行一次连接只是说确定这个设备的deviceId,同时在APP功能正常时能进行连接。只要当uni.createBLEConnection出现开始执行时间与回调结果时间相差只有几十毫秒且回调结果为10012-“createBLEConnection:fail operate time out”时就说明已经出现了异常了。理论上使用一个无效的deviceId,手动连接几十上百次,也能复现该现象。

    2023-04-10 09:59

2***@qq.com

2***@qq.com (作者)

这个是不需要连接蓝牙设备的包,实测也能复现。 操作流程如下:

  1. 点击按钮: “初始化蓝牙模块”;
  2. 点击按钮: “开始自动连接(无效deviceId)"

然后APP就会使用一个无效deviceId进行连接,当连接几十次后,每次自动连接的结果的日志显示间隔为5秒时就说明功能异常了(每次执行连接操作的间隔就是5秒,如果功能正常,间隔会是20秒)。此时点击按钮”停止自动连接“后,点击”开始搜索蓝牙设备“与主动连接的操作结果结果是失败的。

夜空上亮星星

夜空上亮星星

是这样,我这边红米8A没有一次成功连接上蓝牙设备。

  • 2***@qq.com (作者)

    一次都连接不上的话,可能是代码的问题。我这测试是在连接几十次后才连接不上的。你用官方的DEMO试试能不能连上。

    2023-04-17 13:46

5***@qq.com

5***@qq.com

搜索指定services的BLE设备30秒左右,然后关闭搜索(1分钟),使用uni.createBLEConnection连接搜到的BLE设备(7台左右),连接后读取数据,然后关闭连接。
这样循环一定次数后,可以搜到设备,但是调用uni.createBLEConnection,全部都是失败createBLEConnection:fail operate time out,这时候关闭蓝牙适配器,然后再重启,前几次还能成功,后面变成失败

万能的李大少

万能的李大少

我这边主动关闭手机的蓝牙设备后再打开,然后尝试重新链接,会报超时的错误,这个有人遇见过么,无法实现重连操作

x***@163.com

x***@163.com

大佬,这个蓝牙连接超时的问题解决了么?我也遇到这个连接超时的问题

  • 刨地瓜

    无法解决,只能通过开关系统蓝牙、重启APP方式恢复。 不行就只能用三方蓝牙插件来处理。

    2024-01-15 15:04

要回复问题请先登录注册