Android的CompanionDeviceManager Associate()按服务过滤时找不到任何设备

问题描述 投票:0回答:1

我正在使用 Google 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 );

请注意源代码开头的注释行。我知道这段代码有效,因为它的当前状态,它显示了一个包含附近所有 Bluetooth LE 设备的对话框,包括我感兴趣的设备。

当我删除上面的注释标记并通过心率服务进行过滤时,问题就出现了。在我自己的 Android 12 设备中,屏幕上什么也没有出现,甚至没有一个带有空设备列表的对话框。我什至尝试将其留在那里几个小时,但没有任何变化。

我的期望是:

  • 应该有一个对话框或至少一条消息显示设备正在扫描。
  • 该对话框应该超时,然后报告当前过滤器未找到任何设备。

不过,我在调用 API 时可能犯了一些错误。有什么想法吗?任何帮助将不胜感激。

FWIW,我知道这个问题没有答案

java android bluetooth bluetooth-lowenergy
1个回答
0
投票

我在Android 12中使用蓝牙经典时遇到了类似的情况。

就我而言,我使用了 Companion Device Manager API,如下面的代码所示。

fun startDiscovering(activity: Activity) {
    Log.d(
        TAG,
        "discovering state : ${bluetoothAdapter.isDiscovering} findStart!"
    )

    if (!bluetoothAdapter.isDiscovering) {
        _state.value = BluetoothState.STATE_DISCOVERING
        val executor: Executor = Executor { it.run() }
        if(Build.VERSION.SDK_INT>=33){
            deviceManager.associate(pairingRequest, executor, discoveringCallback)
        }else{
            deviceManager.associate(pairingRequest,discoveringCallback,null)
        }

        activity.registerReceiver(receiver, filter)
    }
}

在运行 API 33 的设备上显示系统对话框,但在运行 API 31 的设备上不显示。

总之,我发现

associate()
函数中的回调在 API 31 和 API 33 之间的行为有所不同。

这里是各个版本中

associate()
功能的参考。 (公共部分已省略)

  • API 31


// @param callback will be called once there's at least one device found for user to choose from

public void associate (AssociationRequest request, 
                    CompanionDeviceManager.Callback callback, 
                    Handler handler)
  • API 33
// @param callback The callback used to notify application when the association is created.

public void associate (AssociationRequest request, 
                Executor executor, 
                CompanionDeviceManager.Callback callback)

根据上述注释,在 API 31 上,仅当发现其他设备时才会显示系统对话框。

我相信这就是系统对话框不显示的原因。

就我而言,没有设备与我的过滤器匹配,因此没有显示对话框。

但是,我确认它仍然适用于扫描设备,即使未使用 BroadcastReceiver 调用

onDeviceFound
onFailure
等回调函数。

设备开始发现何时调用

associate()
函数,并在几秒钟后完成。

因此,您可以使用BroadcastReceiver检测发现状态来解决这个问题。

这是一个 IntentFilter,您可以与 本例的广播接收器。

private val filter = IntentFilter().apply {
        addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED)
        addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
    }

PS。英语不是我的母语。所以虽然我努力让它可读,但还是可能会有一些尴尬的表达。😅

© www.soinside.com 2019 - 2024. All rights reserved.