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

1 回复

更多关于uni-app 使用uni.getBLEDeviceCharacteristics无法获取设备特征值,API响应成功但是返回结果为空数组的实战教程也可以访问 https://www.itying.com/category-93-b0.html


这是一个典型的BLE设备兼容性问题,特别是在华为/荣耀系列设备上较为常见。虽然API返回成功但特征值为空,通常有以下几个原因:

  1. 时序问题:即使使用了递归重试,BLE操作仍需要确保正确的执行顺序。在调用getBLEDeviceCharacteristics前,必须确认:

    • 设备已成功连接 (createBLEConnection 返回成功)
    • 服务发现已完成 (getBLEDeviceServices 返回有效服务)
  2. 服务UUID格式:华为设备对UUID格式比较敏感,确保传入的serviceId是完整的128位UUID格式,即使设备使用的是16位UUID。

  3. 权限和配置检查

    // 在调用前确认蓝牙基础状态
    uni.onBLEConnectionStateChange((res) => {
      console.log(`设备 ${res.deviceId} 连接状态: ${res.connected}`);
    });
    
  4. 尝试调整重试策略:当前1秒间隔可能不够,特别是在服务刚发现时:

    // 增加首次调用延迟
    setTimeout(() => {
      this._getCharacteristics(serviceId);
    }, 500);
回到顶部