uni-app app端 蓝牙无法同时监听多个特征值变化 同时调用notifyBLECharacteristicValueChange 只能监听到一个服务的回调信息

发布于 1周前 作者 vueper 来自 Uni-App

uni-app app端 蓝牙无法同时监听多个特征值变化 同时调用notifyBLECharacteristicValueChange 只能监听到一个服务的回调信息

开发环境 版本号 项目创建方式
PC开发环境操作系统 Windows HBuilderX
PC开发环境操作系统版本号 Windows 11 家庭版 -
手机系统 Android -
手机系统版本号 Android 13 -
手机厂商 联想 -
手机机型 PadPlus舒适版 -
页面类型 vue -
vue版本 vue3 -
打包方式 云端 -

示例代码:

uni.getBLEDeviceCharacteristics({  
    deviceId: device.deviceId,  
    serviceId: serviceID,  
    success: res => {  
        for (let i = 0; i < res.characteristics.length; i++) {  
            let item = res.characteristics[i]  
            // 该特征值是否支持 write 操作  
            if (item.properties.write) {  
                if (item.uuid.indexOf("00000AC2") >= 0) {  
                    writeValue.value = {  
                        device: device,  
                        serviceID: serviceID,  
                        characteristicID: item.uuid  
                    }  
                }  
            }  
            //该特征值是否支持 read 操作  
            if (item.properties.read) {  

                readBLECharacteristicValue(device.deviceId, serviceID, item.uuid)  

            }  
            //该特征值是否支持 notify或indicate 操作  
            if (item.properties.notify || item.properties.indicate) {  
                notifyBLECharacteristicValueChange(device.deviceId, serviceID, item.uuid);  
            }  
        }  
    }  
})

操作步骤:

蓝牙设备两个都能notify的特征值,不能一起监听

预期结果:

可以同时监听多个特征值

实际结果:

onBLECharacteristicValueChange只能返回最后一次的值

bug描述:

读取之后和监听两个特征值只能返回最后监听的特征值


1 回复

在uni-app开发中,确实存在蓝牙特性(BLE)同时监听多个特征值变化时可能遇到的问题。notifyBLECharacteristicValueChange API 通常用于订阅某个特征值的变化通知,但如果你尝试同时监听多个特征值,可能会遇到回调冲突或只能接收到一个服务回调的情况。

为了解决这一问题,我们需要确保每个特征值的监听是独立且正确配置的。下面是一个基本的代码示例,展示如何在uni-app中同时监听多个蓝牙特征值的变化。

首先,确保你已经成功连接到蓝牙设备,并获取了服务和特征值的UUID。

// 假设已经通过uni.createBLEConnection连接到了设备,并获取了services和characteristics

// 保存特征值订阅的回调ID,以便后续取消订阅
let notifyIds = {};

function startNotifying(deviceId, serviceId, characteristicId) {
    uni.notifyBLECharacteristicValueChange({
        state: true, // 开启通知
        deviceId: deviceId,
        serviceId: serviceId,
        characteristicId: characteristicId,
        success: (res) => {
            console.log(`Successfully started notifying for ${deviceId}-${serviceId}-${characteristicId}`);
            // 保存回调ID(这里假设res包含某种形式的ID,实际情况可能不同)
            notifyIds[`${deviceId}-${serviceId}-${characteristicId}`] = res.someId; // 假设的ID字段
        },
        fail: (err) => {
            console.error(`Failed to start notifying for ${deviceId}-${serviceId}-${characteristicId}`, err);
        },
    });

    // 监听特征值变化
    uni.onBLECharacteristicValueChange((result) => {
        if (result.deviceId === deviceId && result.serviceId === serviceId && result.characteristicId === characteristicId) {
            console.log(`Received data for ${deviceId}-${serviceId}-${characteristicId}:`, result.value);
        }
    });
}

// 示例:启动两个特征值的通知
startNotifying('your-device-id-1', 'your-service-id-1', 'your-characteristic-id-1');
startNotifying('your-device-id-1', 'your-service-id-2', 'your-characteristic-id-2');

// 注意:在实际应用中,需要处理设备断开连接、应用进入后台等情况,可能需要取消订阅
function stopNotifying(deviceId, serviceId, characteristicId) {
    const id = notifyIds[`${deviceId}-${serviceId}-${characteristicId}`];
    if (id) {
        // 这里假设有一个API可以根据ID取消订阅,实际情况可能不同
        // uni.cancelBLECharacteristicValueChange(id); // 假设的API
    }
}

注意

  • uni.notifyBLECharacteristicValueChange 的回调中通常不包含直接用于后续取消订阅的ID,这里的 res.someId 是假设的。实际使用中,你可能需要自行管理一个映射表来跟踪哪些特征值已经被订阅。
  • uni.onBLECharacteristicValueChange 是一个全局监听器,因此你需要根据 deviceId, serviceId, 和 characteristicId 来区分是哪个特征值的变化。
  • 确保在设备断开连接或应用进入后台时正确取消订阅,以避免资源泄露或不必要的电池消耗。
回到顶部