<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>
- 发布:2023-03-16 16:38
- 更新:2024-10-23 14:56
- 阅读:2004
【报Bug】APP在运行过程中,多次执行uni.createBLEConnection后,uni.createBLEConnection功能异常,无法连接设备
产品分类: uniapp/App
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: window10
HBuilderX类型: 正式
HBuilderX版本号: 3.7.3
手机系统: Android
手机系统版本号: Android 11
手机厂商: 小米
手机机型: 红米note10 pro
页面类型: vue
vue版本: vue2
打包方式: 云端
项目创建方式: HBuilderX
示例代码:
操作步骤:
- 下载压缩包,导入项目。将手机连接电脑,将手机配置调整成可用于真机调试的程度。准备一个可连接的蓝牙设备。 开始真机调试(可使用Hbuilerx的标准基座进行真机调试)。
- 打开手机蓝牙;
- 点击“初始化蓝牙模块”按钮;
- 点击“开始搜索蓝牙设备”按钮;
- 在确定搜索到用于测试的蓝牙设备后,点击”选择设备“按钮,选择该设备;
- 点击”连接蓝牙设备“按钮,确定设备已经连接成功;
- 确定设备已连接后,将蓝牙设备关闭,随后APP会有连接断开的提示弹窗显示,关闭连接断开的提示弹窗;
- 将手机放置不动,此时代码会开始尝试自动连接该蓝牙设备。通过hbuilerX控制台能查看日志。 最开始执行时 ” ------ auto connect device num“与” 连接低功耗蓝牙失败,错误码:10012 “ 两个日志显示的时间会相差15秒。
9 在手机放置了20分钟或更多时间后,” ------ auto connect device num“与” 连接低功耗蓝牙失败,错误码:10012 “ 两个日志显示的时间仅会相差十几毫秒左右。此时功能异常,开启之前关闭的蓝牙设备,观察APP是否能连接上该蓝牙设备。
- 下载压缩包,导入项目。将手机连接电脑,将手机配置调整成可用于真机调试的程度。准备一个可连接的蓝牙设备。 开始真机调试(可使用Hbuilerx的标准基座进行真机调试)。
- 打开手机蓝牙;
- 点击“初始化蓝牙模块”按钮;
- 点击“开始搜索蓝牙设备”按钮;
- 在确定搜索到用于测试的蓝牙设备后,点击”选择设备“按钮,选择该设备;
- 点击”连接蓝牙设备“按钮,确定设备已经连接成功;
- 确定设备已连接后,将蓝牙设备关闭,随后APP会有连接断开的提示弹窗显示,关闭连接断开的提示弹窗;
- 将手机放置不动,此时代码会开始尝试自动连接该蓝牙设备。通过hbuilerX控制台能查看日志。 最开始执行时 ” ------ auto connect device num“与” 连接低功耗蓝牙失败,错误码:10012 “ 两个日志显示的时间会相差15秒。
9 在手机放置了20分钟或更多时间后,” ------ auto connect device num“与” 连接低功耗蓝牙失败,错误码:10012 “ 两个日志显示的时间仅会相差十几毫秒左右。此时功能异常,开启之前关闭的蓝牙设备,观察APP是否能连接上该蓝牙设备。
预期结果:
蓝牙设备开启后,APP执行连接操作响应: {"errMsg":"createBLEConnection:ok"} ; 而后触发uni.onBLEConnectionStateChange监听,提示连接成功。
蓝牙设备开启后,APP执行连接操作响应: {"errMsg":"createBLEConnection:ok"} ; 而后触发uni.onBLEConnectionStateChange监听,提示连接成功。
实际结果:
蓝牙设备开启后,APP执行连接操作响应:{"errMsg":"createBLEConnection:fail operate time out","errCode":10012,"code":10012} ,蓝牙设备未连接成功
蓝牙设备开启后,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功能异常的情况,此时进行搜索操作无法搜索到蓝牙设备。不是一定触发,有一次在手机放置超过半小时后出现了这个现象。
遇见同样的问题,Android为华为Mate20。如果把蓝牙连接超时不设置,默认30s会产生连接超时,间隔2s后再次连接。这样设计,大概把手机放那2~3个小时,就会出现createBLEConnection一直失败,只有重启APP才可恢复。
如果把连接超时设置为15s左右,在1~2次重试连接后,超时事件会从15s自动变化到6~7s左右。然后就开始出现一样的无法连接的问题。
调试过程中,更新JS代码自动重新加载页面(没有重启APP),这时如果把Adapter重新初始化后调用createBLEConnection,也会很容易复现以上问题。所以一直怀疑是不是存在后台多个连接造成的问题。
在每次createBLEConnection前去做一次closeBLEConnection对这个问题有缓解(仅缓解),但最终还是过不了长时间测试。
我们这边在测试的时候发现蓝牙设备在断开重启之后,设备的address可能会变,你看一下你那边的蓝牙设备是不是也是这种情况
-
memedada (作者)
不是的,设备的deviceId没有变化。出现该现象时不仅是之前断开的设备不能连接,其他所有的蓝牙设备都无法连接成功。 测试时一般自动连接50多次后就会出现这个情况,之前放在连接100多次后有出现过连搜索蓝牙设备API都失效的情况。且红米的手机可能多个型号都存在这个问题, 这边测试使用红米note10pro、红米6A都复现了。
2023-04-07 16:55
-
memedada (作者)
回复 DCloud_Android_zl: 小米的手机可能都能测试出这个问题。这边最开始就是小米12测出这个现象的。项目APP蓝牙功能异常后,BLE调试助手也运行异常了,无法搜索到任何设备,而系统蓝牙则能正常搜索设备。 且出现这个现象的场景与APP运行期间调用过的uni.createBLEConnection总次数有关系。测试每自动连接10次左右再让其连接成功,然后再关闭蓝牙设备断开连接, 如果重复五六次后,也出现了蓝牙异常情况的情况。
2023-04-07 17:54
-
memedada (作者)
回复 DCloud_Android_zl: 这个对蓝牙设备没要求的,只要该设备支持低功耗蓝牙,能被搜索并连接到就行。本质是要让APP执行蓝牙连接次数超过一个数,这个数可能是50,也可以是90,就会导致APP蓝牙功能异常。 我这使用过小米的手环也能复现。使用设备进行一次连接只是说确定这个设备的deviceId,同时在APP功能正常时能进行连接。只要当uni.createBLEConnection出现开始执行时间与回调结果时间相差只有几十毫秒且回调结果为10012-“createBLEConnection:fail operate time out”时就说明已经出现了异常了。理论上使用一个无效的deviceId,手动连接几十上百次,也能复现该现象。
2023-04-10 09:59
memedada (作者)
这个是不需要连接蓝牙设备的包,实测也能复现。 操作流程如下:
- 点击按钮: “初始化蓝牙模块”;
- 点击按钮: “开始自动连接(无效deviceId)"
然后APP就会使用一个无效deviceId进行连接,当连接几十次后,每次自动连接的结果的日志显示间隔为5秒时就说明功能异常了(每次执行连接操作的间隔就是5秒,如果功能正常,间隔会是20秒)。此时点击按钮”停止自动连接“后,点击”开始搜索蓝牙设备“与主动连接的操作结果结果是失败的。
搜索指定services的BLE设备30秒左右,然后关闭搜索(1分钟),使用uni.createBLEConnection连接搜到的BLE设备(7台左右),连接后读取数据,然后关闭连接。
这样循环一定次数后,可以搜到设备,但是调用uni.createBLEConnection,全部都是失败createBLEConnection:fail operate time out,这时候关闭蓝牙适配器,然后再重启,前几次还能成功,后面变成失败
7***@qq.com - 0->1
mark一下,坐等大佬。
同一个APP连接蓝牙,前几次可以成功,后面基本就失败了报错10012,把目标蓝牙设备断电然后再启动,APP杀掉重启,貌似又可以连接,几次之后又不行了
s***@163.com
解决了嘛?
2024-10-22 11:26