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

Android CompanionDeviceManager按服务过滤时associate()无法发现设备

问题描述

我正在使用Android的CompanionDeviceManager API查找附近支持心率测量的Bluetooth LE设备。代码如下:

final BluetoothLeDeviceFilter DEVICE_FILTER =
                new BluetoothLeDeviceFilter.Builder()
                    .setScanFilter( new ScanFilter.Builder()
                    /*    .setServiceUuid(
                                ParcelUuid.fromString( "0000180D-0000-1000-8000-00805f9b34fb" )
                    */
                        .build() ).build();

final AssociationRequest PAIRING_REQ = new AssociationRequest.Builder()
                .addDeviceFilter( DEVICE_FILTER )
                .setSingleDevice( false )
                .build();

final CompanionDeviceManager DEV_MANAGER =
                (CompanionDeviceManager) getSystemService(
                                    Context.COMPANION_DEVICE_SERVICE );

DEV_MANAGER.associate( PAIRING_REQ, new CompanionDeviceManager.Callback() {
        @Override
        public void onDeviceFound(@NonNull IntentSender chooserLauncher)
        {            
            try {
                startIntentSenderForResult( chooserLauncher, RCQ_SELECT_DEVICE,
                                        null, 0, 0, 0 );
            } catch (IntentSender.SendIntentException e) {
                Log.e( LOG_TAG, "onAssociationPending: failed to send intent" );
            }
        }
        @Override
        public void onFailure(CharSequence errorMessage)
        {
            Log.e( LOG_TAG, "[FAIL] " + errorMessage );
        }
    }, null );

未启用服务过滤时,代码可正常弹出显示所有附近BLE设备的对话框,包含目标设备;但移除注释启用心率服务UUID(0000180D-0000-1000-8000-00805f9b34fb)过滤后,在Android 12设备上无任何界面反馈,连空设备列表对话框都不出现,即使等待数小时也无变化。预期是显示扫描状态对话框或提示,超时后提示未找到符合过滤条件的设备,怀疑API调用存在错误,寻求解决方案。已知有未解决的同类问题。

解决方案

针对Android 12上CompanionDeviceManager启用心率服务过滤无反馈的问题,可尝试以下修复方案:

1. 完善扫描过滤的UUID匹配模式

仅设置setServiceUuid可能因设备广播格式问题导致过滤失效,需添加部分匹配模式:

.setServiceUuid(
    ParcelUuid.fromString("0000180D-0000-1000-8000-00805f9b34fb"),
    BluetoothDevice.SCAN_FILTER_UUID_PARTIAL_MATCH
)

该模式允许匹配广播中包含的部分UUID,兼容更多设备的广播格式。

2. 配置扫描超时

默认扫描无明确超时,需在AssociationRequest中设置超时时长,超时后会触发onFailure回调:

final AssociationRequest PAIRING_REQ = new AssociationRequest.Builder()
        .addDeviceFilter(DEVICE_FILTER)
        .setSingleDevice(false)
        .setTimeoutSeconds(30) // 设置30秒扫描超时
        .build();

可在onFailure中添加用户提示,告知未找到设备。

3. 确认权限配置

Android 12及以上版本,BLE扫描需BLUETOOTH_SCAN权限,且需在Manifest中声明权限用途:

<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />

若应用需通过BLE获取位置,需将neverForLocation替换为forLocation,同时确保已动态申请ACCESS_FINE_LOCATION权限。

4. 验证目标设备的广播数据

部分心率设备不会主动广播180D服务UUID,此时CompanionDeviceManager的过滤无法识别。可先用普通BLE扫描捕获设备广播:

BluetoothLeScanner scanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
scanner.startScan(new ScanCallback() {
    @Override
    public void onScanResult(int callbackType, ScanResult result) {
        List<ParcelUuid> uuids = result.getScanRecord().getServiceUuids();
        if (uuids != null) {
            for (ParcelUuid uuid : uuids) {
                Log.d("BLE_SCAN", "设备UUID: " + uuid.toString());
            }
        }
    }
});

若目标设备未广播该UUID,可补充设备名称过滤:

new ScanFilter.Builder()
        .setServiceUuid(ParcelUuid.fromString("0000180D-0000-1000-8000-00805f9b34fb"))
        .setDeviceName("你的心率设备名称")
        .build()

5. 补充超时兜底逻辑

若onFailure未正常触发,可在启动扫描后手动设置定时器,超时后主动提示用户:

new Handler(Looper.getMainLooper()).postDelayed(() -> {
    Toast.makeText(this, "未找到符合条件的心率设备", Toast.LENGTH_SHORT).show();
}, 35000); // 比设置的超时多5秒,避免提前触发

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 07:30:15