You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 12(targetSdkVersion31)BLE自定义serviceUUID获取异常求助

Android 12 (targetSdk31) BLE Scan Response 获取问题解决

行为变更原因

Android 12(对应targetSdkVersion 31)调整了BLE扫描的默认行为——系统不再自动向BLE设备请求Scan Response包。此前targetSdkVersion 30及以下版本,系统会在扫描到广播包后自动触发Scan Response请求,因此你能直接从ScanRecord中获取到包含在Scan Response里的自定义Service UUID;但升级后这个默认行为被移除,仅当扫描时显式配置相关参数,才会主动请求Scan Response。

解决方法

1. 启用非传统扫描模式触发Scan Response请求

使用ScanSettings.Builder时添加setLegacy(false),启用非传统扫描模式。该模式下系统会主动请求Scan Response包,你就能在ScanResult中拿到完整的ScanRecord。

示例代码:

ScanSettings scanSettings = new ScanSettings.Builder()
        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
        .setLegacy(false) // 关键配置,触发Scan Response请求
        .build();

// 启动扫描(可先不设置过滤,后续手动校验)
bluetoothLeScanner.startScan(null, scanSettings, scanCallback);

注:非传统扫描模式仅支持Android 8.0+,你的targetSdk31覆盖的系统版本均满足要求。

2. 手动触发Scan Response请求

如果上述方法不生效,可在扫描到设备后,调用BluetoothDevice.readRemoteRssi()触发设备发送Scan Response。该操作无需连接设备,触发后会在ScanCallback的onScanResult中返回包含完整Service UUID的ScanRecord。

3. 正确处理UUID过滤

因为目标Service UUID在Scan Response中,直接用ScanFilter按UUID过滤会失效(过滤仅基于广播包数据),需改为:

  • 不设置ScanFilter,先扫描所有BLE设备;
  • 在ScanCallback的onScanResult中解析ScanRecord,手动校验是否包含目标自定义128位UUID。

解析示例代码:

private final ScanCallback scanCallback = new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        super.onScanResult(callbackType, result);
        ScanRecord scanRecord = result.getScanRecord();
        if (scanRecord == null) return;

        List<ParcelUuid> serviceUuids = scanRecord.getServiceUuids();
        if (serviceUuids != null) {
            UUID targetUuid = UUID.fromString("你的自定义128位UUID");
            for (ParcelUuid uuid : serviceUuids) {
                if (uuid.getUuid().equals(targetUuid)) {
                    // 找到目标设备,执行后续逻辑
                    break;
                }
            }
        }
    }
};

额外注意事项

  • 权限配置:Android 12+需在Manifest中声明BLUETOOTH_SCAN权限,若无需位置信息,需添加android:usesPermissionFlags="neverForLocation"避免请求位置权限;
  • 运行时权限:需在代码中主动请求BLUETOOTH_SCAN权限,否则扫描会失败;
  • 设备验证:使用BLE调试工具(如nRF Connect)确认你的传感器确实在Scan Response中包含目标Service UUID,排除设备端问题。

内容的提问来源于stack exchange,提问作者Ray

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 09:40:42