uni-app 低功耗蓝牙的监听事件无法移除
uni-app 低功耗蓝牙的监听事件无法移除
| 类别 | 信息 |
|---|---|
| 产品分类 | uniapp/App |
| PC开发环境操作系统 | Mac |
| PC开发环境操作系统版本号 | Mac min Apple M1 |
| HBuilderX类型 | 正式 |
| HBuilderX版本号 | 4.66 |
| 手机系统 | Android |
| 手机系统版本号 | Android 15 |
| 手机厂商 | 小米 |
| 手机机型 | REDMI K80 Pro |
| 页面类型 | vue |
| vue版本 | vue3 |
| 打包方式 | 云端 |
| 项目创建方式 | HBuilderX |
操作步骤:
/** 开锁 */
const openLock = () => {
uni.showLoading({
title: '正在开锁',
mask: true
});
uni.getBLEDeviceCharacteristics({
deviceId: deviceId.value,
serviceId: targetServiceId
});
const instruction = calculateUnlockingInstructions(deviceId.value);
const data = hex2ArrayBuffer(instruction);
if (!isCreateListener.value) {
createListener();
}
setTimeout(async () => {
await sendToDevice(deviceId.value, hex2ArrayBuffer(obtainElectricity));
await sendToDevice(deviceId.value, data);
uni.hideLoading();
}, 800);
};
/** 创建监听 */
const createListener = () => {
uni.notifyBLECharacteristicValueChange({
deviceId: deviceId.value,
serviceId: targetServiceId,
characteristicId: targetCharacteristicId_NOTIFY,
state: true,
success: () => {
if (!isCreateListener.value) {
isCreateListener.value = true;
uni.onBLECharacteristicValueChange((res) => {
let result = ab2hex(res.value as any);
if (result.indexOf('50') > -1) {
const decode = xOr(`${deviceId.value}:${result.slice(6, 8)}`);
const power = parseInt(decode, 16);
uni.showModal({
content: `电量${power}`
});
}
});
}
},
fail: (err) => {
uni.showModal({
content: `启动notify失败,原因${err.errMsg},错误码${err.code}`
});
}
});
};
预期结果:
创建一次监听代码每次执行都会触发监听
实际结果:
但是只执行一次,如果多次创建就会一直叠加监听效果
bug描述:
低功耗蓝牙的监听事件无法移除,使用closeBluetoothAdapter和closeBLEConnection都没有效果,如果只创建一次那么onBLECharacteristicValueChange就执行一次,如果创建多次那么监听效果就无限叠加
更多关于uni-app 低功耗蓝牙的监听事件无法移除的实战教程也可以访问 https://www.itying.com/category-93-b0.html
1 回复
更多关于uni-app 低功耗蓝牙的监听事件无法移除的实战教程也可以访问 https://www.itying.com/category-93-b0.html
这是一个典型的蓝牙事件监听器重复注册问题。在uni-app中,uni.onBLECharacteristicValueChange是一个全局事件监听器,每次调用createListener()都会注册一个新的监听器,导致回调函数被重复执行。
问题核心在于:
uni.onBLECharacteristicValueChange没有对应的移除方法- 使用
isCreateListener.value标志位无法阻止重复注册 - 关闭蓝牙适配器或连接不会自动移除已注册的监听器
解决方案:
let characteristicValueCallback = null;
/** 创建监听 */
const createListener = () => {
if (characteristicValueCallback) {
return; // 避免重复注册
}
uni.notifyBLECharacteristicValueChange({
deviceId: deviceId.value,
serviceId: targetServiceId,
characteristicId: targetCharacteristicId_NOTIFY,
state: true,
success: () => {
characteristicValueCallback = (res) => {
let result = ab2hex(res.value);
if (result.indexOf('50') > -1) {
const decode = xOr(`${deviceId.value}:${result.slice(6, 8)}`);
const power = parseInt(decode, 16);
uni.showModal({
content: `电量${power}`
});
}
};
uni.onBLECharacteristicValueChange(characteristicValueCallback);
},
fail: (err) => {
uni.showModal({
content: `启动notify失败,原因${err.errMsg},错误码${err.code}`
});
}
});
};
/** 移除监听 */
const removeListener = () => {
if (characteristicValueCallback) {
// 由于uni-app没有提供直接移除的方法,需要通过关闭notify来间接移除
uni.notifyBLECharacteristicValueChange({
deviceId: deviceId.value,
serviceId: targetServiceId,
characteristicId: targetCharacteristicId_NOTIFY,
state: false,
success: () => {
characteristicValueCallback = null;
isCreateListener.value = false;
}
});
}
};

