uni-app 使用uni.getBLEDeviceCharacteristics无法获取设备特征值,API响应成功但是返回结果为空数组
uni-app 使用uni.getBLEDeviceCharacteristics无法获取设备特征值,API响应成功但是返回结果为空数组
| 开发环境 | 版本号 | 项目创建方式 |
|---|---|---|
| Mac | 14.5 (23F79) | HBuilderX |
产品分类:uniapp/App
PC开发环境操作系统:Mac
HBuilderX类型:正式
HBuilderX版本号:4.76
手机系统:Android
手机系统版本号:Android 12
手机厂商:华为
手机机型:华为荣耀60se
页面类型:vue
vue版本:vue3
打包方式:离线
项目创建方式:HBuilderX
示例代码:
递归获取设备服务
_getCharacteristics(serviceId: string) {
const deviceId = this._deviceId;
const maxAttempts = 10;
let attempt = 0;
const tryGetCharacteristics = (): Promise<any[]> => {
return new Promise((resolve, reject) => {
uni.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success(res: any) {
if (res.characteristics && res.characteristics.length > 0) {
resolve(res.characteristics);
} else if (attempt < maxAttempts - 1) {
attempt++;
setTimeout(() => {
tryGetCharacteristics().then(resolve).catch(reject);
}, 1000);
} else {
resolve(res.characteristics);
}
},
fail(e: any) {
if (attempt < maxAttempts - 1) {
attempt++;
setTimeout(() => {
tryGetCharacteristics().then(resolve).catch(reject);
}, 1000);
} else {
reject(new BluetoothError(e));
}
},
});
});
};
return tryGetCharacteristics();
}
递归获取设备特征值
_getCharacteristics(serviceId: string) {
const deviceId = this._deviceId;
const maxAttempts = 10;
let attempt = 0;
const tryGetCharacteristics = (): Promise<any[]> => {
return new Promise((resolve, reject) => {
uni.getBLEDeviceCharacteristics({
deviceId,
serviceId,
success(res: any) {
if (res.characteristics && res.characteristics.length > 0) {
resolve(res.characteristics);
} else if (attempt < maxAttempts - 1) {
attempt++;
setTimeout(() => {
tryGetCharacteristics().then(resolve).catch(reject);
}, 1000);
} else {
resolve(res.characteristics);
}
},
fail(e: any) {
if (attempt < maxAttempts - 1) {
attempt++;
setTimeout(() => {
tryGetCharacteristics().then(resolve).catch(reject);
}, 1000);
} else {
reject(new BluetoothError(e));
}
},
});
});
};
return tryGetCharacteristics();
}
操作步骤:
预期结果:
{
"characteristics": [
{
"uuid": "0000FF01-0000-1000-8000-00805F9B34FB",
"properties": {
"read": false,
"write": true,
"notify": false,
"indicate": false
}
},
{
"uuid": "0000FF02-0000-1000-8000-00805F9B34FB",
"properties": {
"read": true,
"write": false,
"notify": true,
"indicate": false
}
}
],
"errMsg": "getBLEDeviceCharacteristics:ok"
}
实际结果:
{
"characteristics": [],
"errMsg": "getBLEDeviceCharacteristics:ok"
}
bug描述:
测试过一加、红米、华为荣耀60、华为荣耀60se、pixel这些安卓手机,目前发现华为荣耀60se使用getBLEDeviceServices无法拿到服务uuid,看了社区有说增加延时可以拿到,所以在调用getBLEDeviceServices时使用了递归的方式。测试发现确实能拿到设备的服务uuid,但是使用设备id和设备服务uuid去获取特征值时,得到的一直是空数组。获取特征值的方法也使用了递归的方式。(在荣耀60se使用其它的蓝牙助手工具却能看到服务和特征值)
更多关于uni-app 使用uni.getBLEDeviceCharacteristics无法获取设备特征值,API响应成功但是返回结果为空数组的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于uni-app 使用uni.getBLEDeviceCharacteristics无法获取设备特征值,API响应成功但是返回结果为空数组的实战教程也可以访问 https://www.itying.com/category-93-b0.html
这是一个典型的BLE设备兼容性问题,特别是在华为/荣耀系列设备上较为常见。虽然API返回成功但特征值为空,通常有以下几个原因:
-
时序问题:即使使用了递归重试,BLE操作仍需要确保正确的执行顺序。在调用
getBLEDeviceCharacteristics前,必须确认:- 设备已成功连接 (
createBLEConnection返回成功) - 服务发现已完成 (
getBLEDeviceServices返回有效服务)
- 设备已成功连接 (
-
服务UUID格式:华为设备对UUID格式比较敏感,确保传入的serviceId是完整的128位UUID格式,即使设备使用的是16位UUID。
-
权限和配置检查:
// 在调用前确认蓝牙基础状态 uni.onBLEConnectionStateChange((res) => { console.log(`设备 ${res.deviceId} 连接状态: ${res.connected}`); }); -
尝试调整重试策略:当前1秒间隔可能不够,特别是在服务刚发现时:
// 增加首次调用延迟 setTimeout(() => { this._getCharacteristics(serviceId); }, 500);

