Search code examples
androidrxandroidble

Rxandroidble-The method scanBleDevices(UUID... filters) is not support for two types service


I got a problem that the method scanBleDevices(UUID... filters) cannot support to discover double kind of devices with different UUIDServices.

I guess that the relationship between the args are AND, but not OR. But How could I get the double kind of device with different UUIDService?

The code under there is that I want to discover the device with the uuid 00001801-0000-1000-8000-00805F9B34FB and another device with uuid 6E400001-B5A3-F393-E0A9-E50E24DCCA9E , But i always cannot get the result with the code. So, how can I solve the question?

scanScription = rxBleClient
            .scanBleDevices(UUID.fromString("00001801-0000-1000-8000-00805F9B34FB"),  UUID.fromString("6E400001-B5A3-F393-E0A9-E50E24DCCA9E"))
            .subscribe(new Action1<RxBleScanResult>() {
        @Override
        public void call(RxBleScanResult rxBleScanResult) {
            if (!bleDeviceHashMap.containsKey(rxBleScanResult.getBleDevice().getMacAddress())) {
                bleDeviceHashMap.put(rxBleScanResult.getBleDevice().getMacAddress(), rxBleScanResult.getBleDevice());
                HashMap<String, String> ble = new HashMap<String, String>();
                ble.put("name", rxBleScanResult.getBleDevice().getName());
                ble.put("address", rxBleScanResult.getBleDevice().getMacAddress());
                bleDevices.add(ble);
                adapter.notifyDataSetChanged();
            }
        }
    });

Solution

  • You can perform your own filtering:

    final UUIDUtil uuidUtil = new UUIDUtil(); // an util class for parsing advertisement scan record byte[] into UUIDs (part of the RxAndroidBle library)
    scanSubscription = rxBleClient
            .scanBleDevices()
            .filter(rxBleScanResult -> {
                final List<UUID> uuids = uuidUtil.extractUUIDs(rxBleScanResult.getScanRecord());
                return uuids.contains(firstUuid) || uuids.contains(secondUuid);
            })
            .subscribe(
                ...
            );
    

    You can also split it into two flows right away:

        final UUIDUtil uuidUtil = new UUIDUtil();
        final Observable<RxBleScanResult> sharedScanResultObservable = rxBleClient
                .scanBleDevices()
                .share(); // sharing the scan between two subscriptions
    
        firstScanSubscription = sharedScanResultObservable
                .filter(rxBleScanResult -> uuidUtil
                        .extractUUIDs(rxBleScanResult.getScanRecord())
                        .contains(firstUuid)) // checking for the first UUID
                .subscribe(
                    // reacting for the first type of devices        
                );
    
        secondScanSubscription = sharedScanResultObservable
                .filter(rxBleScanResult -> uuidUtil
                        .extractUUIDs(rxBleScanResult.getScanRecord())
                        .contains(secondUuid)) // checking for the second UUID
                .subscribe(
                    // reacting for the second type of devices
                );