uni-app使用uni.startBluetoothDevicesDiscovery时若services参数传入的Array长度大于1将产生没有搜索到任何设备的现象

uni-app使用uni.startBluetoothDevicesDiscovery时若services参数传入的Array长度大于1将产生没有搜索到任何设备的现象

开发环境 版本号 项目创建方式
Windows 22H2 HBuilderX

产品分类:uniapp/App

PC开发环境操作系统:Windows

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

HBuilderX类型:正式

HBuilderX版本号:4.75

手机系统:Android

手机系统版本号:Android 15

手机厂商:一加

手机机型:一加12

页面类型:vue

vue版本:vue3

打包方式:云端

示例代码:

// services参数传入数组长度为1时,结果正常  
uni.startBluetoothDevicesDiscovery({  
    services: [  
        "0000FFF0-0000-1000-8000-00805F9B34FB"  
    ],  
    success(res) {  
        uni.onBluetoothDeviceFound(res => {  
                // 可以获取到所过滤到的设备列表  
        })  
    }  
})  

// services参数传入数组长度大于1时,无法搜索到任何设备  
uni.startBluetoothDevicesDiscovery({  
    services: [  
        "0000FFF0-0000-1000-8000-00805F9B34FB",  
        "0000ae00-0000-1000-8000-00805f9b34fb",  
    ],  
    success(res) {  
        uni.onBluetoothDeviceFound(res => {  
                // 无法获取到设备列表(onBluetoothDeviceFound未触发)  
        })  
    }  
})

操作步骤:

// services参数传入数组长度大于1时,无法搜索到任何设备  
uni.startBluetoothDevicesDiscovery({  
    services: [  
        "0000FFF0-0000-1000-8000-00805F9B34FB",  
        "0000ae00-0000-1000-8000-00805f9b34fb",  
    ],  
    success(res) {  
        uni.onBluetoothDeviceFound(res => {  
                // 无法获取到设备列表(onBluetoothDeviceFound未触发)  
        })  
    }  
})

预期结果:

uni.startBluetoothDevicesDiscovery的参数services传入的Array长度大于1时(即传入多个主sevice时),最终onBluetoothDeviceFound应触发并返回满足“符合任一主service”的蓝牙设备列表。

实际结果:

uni.startBluetoothDevicesDiscovery的参数services传入的Array长度大于1时(即传入多个主sevice时),无法搜索到任何设备(抑或可能是所有设备都被过滤掉了)

bug描述:

在使用uni.startBluetoothDevicesDiscovery方法时,services参数传入的Array长度若大于1,会导致最终无法搜索到任何设备,只有传入的Array长度等于1时才能正常搜索并过滤到设备。


更多关于uni-app使用uni.startBluetoothDevicesDiscovery时若services参数传入的Array长度大于1将产生没有搜索到任何设备的现象的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

我试了下,安卓调用2次uni.startBluetoothDevicesDiscovery,分别传入不同的service是生效的,苹果调用2次,只有第1次生效。

更多关于uni-app使用uni.startBluetoothDevicesDiscovery时若services参数传入的Array长度大于1将产生没有搜索到任何设备的现象的实战教程也可以访问 https://www.itying.com/category-93-b0.html


解决办法,前提是设备的广播中要有advertisServiceUUIDs,
uni.onBluetoothDeviceFound(res => { //把搜索到的设备进行一次筛选 let arr = []; let serviceDic = [“0000FFF0-0000-1000-8000-00805F9B34FB”, “0000ae00-0000-1000-8000-00805f9b34fb”];
for (var i = 0; i < res.devices.length; i++) {
let item = res.devices[i];
let f = serviceDic.find(v => {
return item.advertisServiceUUIDs.includes(v.serviceId);
});
if (f) {
arr.push(item);
}

}
if (arr.length === 0) {
return;
}
//对devices参数进行重新赋值
res.devices = arr;

//继续执行回调函数其它内容
})

这是一个已知的蓝牙设备发现限制问题。在uni-app的蓝牙API实现中,当services参数传入多个UUID时,底层会执行"与"逻辑而非"或"逻辑,即要求设备必须同时包含所有指定的服务UUID才会被返回。

从你的测试结果可以看出:

  • 单个UUID:正常过滤包含该服务的设备
  • 多个UUID:由于设备很难同时包含所有指定服务,导致过滤结果为空

当前建议的解决方案:

  1. 分批扫描:对每个服务UUID分别调用uni.startBluetoothDevicesDiscovery
  2. 不使用services过滤:先获取所有设备,在onBluetoothDeviceFound回调中手动过滤
  3. 使用allowDuplicatesKey:配合设备去重逻辑处理重复设备

示例代码:

// 方案1:分批扫描
const serviceUUIDs = [
  "0000FFF0-0000-1000-8000-00805F9B34FB",
  "0000ae00-0000-1000-8000-00805f9b34fb"
];

for (const service of serviceUUIDs) {
  uni.startBluetoothDevicesDiscovery({
    services: [service],
    success(res) {
      uni.onBluetoothDeviceFound(deviceFoundCallback);
    }
  });
}
回到顶部