【问题标题】:How to filter nearby bluetooth devices by type如何按类型过滤附近的蓝牙设备
【发布时间】:2021-02-16 10:31:00
【问题描述】:

我想扫描并绑定附近运行 WearOS 的安卓智能手表。我按照此处的说明使用 CompanionDeviceManager:https://developer.android.com/guide/topics/connectivity/companion-device-pairing

CompanionDeviceManager 始终显示所有设备类型的列表,包括其他手机、笔记本电脑、蓝牙扬声器和手表(绑定和未配对)。与 Google Wear OS 应用程序相比,它还使用 CompanionDeviceManager(因为我看到了相同的弹出 UI)并且它始终只显示 Android Watch。

它如何在众多其他蓝牙设备中过滤智能手表?

这是我的代码:

private  fun scanLeDevice(enable: Boolean) {
    val deviceFilter: BluetoothLeDeviceFilter = BluetoothLeDeviceFilter.Builder()
        .build()

    // The argument provided in setSingleDevice() determines whether a single
    // device name or a list of device names is presented to the user as
    // pairing options.
    val pairingRequest: AssociationRequest = AssociationRequest.Builder()
        .setSingleDevice(false)
        .addDeviceFilter(deviceFilter)
        .build()

    // When the app tries to pair with the Bluetooth device, show the
    // appropriate pairing request dialog to the user.
    deviceManager.associate(pairingRequest,
        object : CompanionDeviceManager.Callback() {

            override fun onDeviceFound(chooserLauncher: IntentSender) {
                startIntentSenderForResult(chooserLauncher,
                    Companion.SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0)
            }

            override fun onFailure(error: CharSequence?) {
                // Handle failure
            }
        }, null)
}

【问题讨论】:

    标签: android wear-os android-bluetooth


    【解决方案1】:

    备注:这不是完整的答案,因为我不知道每种设备类型的过滤掩码到底是什么,但至少它可以帮助过滤 Android 智能手表

    我反编译了 Google WearOS 应用并查看了源文件 FindDeviceControllerSdk26.java。以下是感兴趣的东西:

     private static final byte[] BLE_WEAR_MATCH_DATA = { 0, 20 };
      private static final byte[] BLE_WEAR_MATCH_DATA_LEGACY = { 0, 19 };
      private static final byte[] BLE_WEAR_MATCH_MASK = { 0, -1 };
      private final void showAssociationDialog()
      {
        Object localObject1 = new ArrayList();
        Object localObject3 = new FindDeviceDeviceFilterBuilder();
        medium = 1;
        Object localObject4 = new ScanFilter.Builder();
        byte[] arrayOfByte = BLE_WEAR_MATCH_DATA;
        Object localObject2 = BLE_WEAR_MATCH_MASK;
        scanFilter = ((ScanFilter.Builder)localObject4).setManufacturerData(224, arrayOfByte, (byte[])localObject2).build();
        FindDeviceAssociationRequestBuilder.unbox_addDeviceFilter$ar$ds((FindDeviceDeviceFilterBuilder)localObject3, (List)localObject1);
        localObject3 = new FindDeviceDeviceFilterBuilder();
        medium = 1;
        scanFilter = new ScanFilter.Builder().setManufacturerData(224, BLE_WEAR_MATCH_DATA_LEGACY, (byte[])localObject2).build();
        FindDeviceAssociationRequestBuilder.unbox_addDeviceFilter$ar$ds((FindDeviceDeviceFilterBuilder)localObject3, (List)localObject1);
        if (!deviceWhitelist.shouldShowAllDevices())
        {
          localObject2 = (GServicesFindDeviceWhitelist)deviceWhitelist;
          ((GServicesFindDeviceWhitelist)localObject2).initializeIfNecessary();
          localObject2 = cachedDeviceWhitelistRegularExpression;
          if (!TextUtils.isEmpty((CharSequence)localObject2))
          {
            localObject3 = new FindDeviceDeviceFilterBuilder();
            medium = 0;
            namePatternString = ((String)localObject2);
            FindDeviceAssociationRequestBuilder.unbox_addDeviceFilter$ar$ds((FindDeviceDeviceFilterBuilder)localObject3, (List)localObject1);
          }
        }
        else
        {
          localObject2 = new FindDeviceDeviceFilterBuilder();
          medium = 0;
          namePatternString = ".*";
          FindDeviceAssociationRequestBuilder.unbox_addDeviceFilter$ar$ds((FindDeviceDeviceFilterBuilder)localObject2, (List)localObject1);
        }
        localObject2 = new AssociationRequest.Builder().setSingleDevice(false);
        localObject3 = ((List)localObject1).iterator();
        while (((Iterator)localObject3).hasNext())
        {
          localObject1 = (FindDeviceDeviceFilterBuilder)((Iterator)localObject3).next();
          if (medium != 0)
          {
            localObject4 = new BluetoothLeDeviceFilter.Builder();
            localObject1 = scanFilter;
            if (localObject1 != null) {
              ((BluetoothLeDeviceFilter.Builder)localObject4).setScanFilter((ScanFilter)localObject1);
            }
            localObject1 = ((BluetoothLeDeviceFilter.Builder)localObject4).build();
          }
          else
          {
            localObject4 = new BluetoothDeviceFilter.Builder();
            if (!Platform.stringIsNullOrEmpty(namePatternString)) {
              ((BluetoothDeviceFilter.Builder)localObject4).setNamePattern(Pattern.compile(namePatternString));
            }
            localObject1 = ((BluetoothDeviceFilter.Builder)localObject4).build();
          }
          ((AssociationRequest.Builder)localObject2).addDeviceFilter((DeviceFilter)localObject1);
        }
        localObject1 = ((AssociationRequest.Builder)localObject2).build();
        viewClient.hideRefreshButton();
        cwEventLogger.incrementCounter(Counter.COMPANION_PAIR_CDM_ASSOCIATE_REQUEST);
        companionDeviceManager.associate((AssociationRequest)localObject1, deviceManagerCallback, null);
      }
      
    

    然后我重写我的扫描功能如下

        private val BLE_WEAR_MATCH_DATA = byteArrayOf(0, 20)
        private val BLE_WEAR_MATCH_DATA_LEGACY = byteArrayOf(0, 19)
        private val BLE_WEAR_MATCH_MASK = byteArrayOf(0, -1)
       private  fun scanLeDevice(enable: Boolean) {
            val scanFilter = ScanFilter.Builder().setManufacturerData(224,BLE_WEAR_MATCH_DATA_LEGACY,BLE_WEAR_MATCH_MASK).build()
            val deviceFilter: BluetoothLeDeviceFilter = BluetoothLeDeviceFilter.Builder()
                .setScanFilter(scanFilter)
                .setNamePattern(Pattern.compile(".*"))
                .build()
            // The argument provided in setSingleDevice() determines whether a single
            // device name or a list of device names is presented to the user as
            // pairing options.
            val pairingRequest: AssociationRequest = AssociationRequest.Builder()
                .setSingleDevice(false)
                .addDeviceFilter(deviceFilter)
                .build()
    
            // When the app tries to pair with the Bluetooth device, show the
            // appropriate pairing request dialog to the user.
            deviceManager.associate(pairingRequest,
                object : CompanionDeviceManager.Callback() {
    
                    override fun onDeviceFound(chooserLauncher: IntentSender) {
                        startIntentSenderForResult(chooserLauncher,
                            Companion.SELECT_DEVICE_REQUEST_CODE, null, 0, 0, 0)
                    }
    
                    override fun onFailure(error: CharSequence?) {
                        // Handle failure
                    }
                }, null)
        }
    

    我希望有人可以帮助描述这些面具代表什么,然后我将帮助更新以完全回答这个问题。

    私有值 BLE_WEAR_MATCH_DATA = byteArrayOf(0, 20)

    私有值 BLE_WEAR_MATCH_DATA_LEGACY = byteArrayOf(0, 19)

    私有值 BLE_WEAR_MATCH_MASK = byteArrayOf(0, -1)

    【讨论】:

      【解决方案2】:

      请看那篇文章:https://medium.com/@martijn.van.welie/making-android-ble-work-part-1-a736dcd53b02

      TL;TR

      String[] names = new String[]{"Polar H7 391BB014"};
      List<ScanFilter> filters = null;
      if(names != null) {
          filters = new ArrayList<>();
          for (String name : names) {
              ScanFilter filter = new ScanFilter.Builder()
                      .setDeviceName(name)
                      .build();
              filters.add(filter);
          }
      }
      scanner.startScan(filters, scanSettings, scanCallback);
      

      【讨论】:

      • 感谢@Maxim 的回答,很遗憾,我们不能强制所有智能手表都有指定的名称才能找到。如果我们需要扫描任何名称的可穿戴设备会怎样?
      • 看起来像手表这样的设备有一个特殊的 UUID 服务来过滤它们。可以通过服务 UUID 进行过滤。
      • 是的,Maxim,同样的想法。我正在寻找这样的服务 UUID,以便我可以过滤任何类型的设备
      【解决方案3】:

      尝试重新启动您的设备。只是第一次,一旦它出现在 SmartWatch 应用程序列表中,您可能不会遇到同样的麻烦。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多