RxAndroidBle如何从多个服务读取通知?

时间:2019-02-27 11:42:30

标签: java android bluetooth rx-java rxandroidble

我使用rxandroid:2.1.0,rxjava:1.4.0和rxandroidble:1.8.1。

我试图连接到设备并接收来自位于不同服务(温度服务,电池服务,自定义服务)中的特征的通知。

我已经访问了大量页面,但是没有找到合适的解决方案。也许有人对如何做到这一点有想法?

2 个答案:

答案 0 :(得分:0)

I have posted my answer here [Programmatically turning on all notifications.

I couldn't make it with rxAndroidBle library, but standart one was good enoygh for my purposes.

答案 1 :(得分:0)

要在任何给定的外围设备上设置所有可能的通知/指示,需要首先连接到设备,然后发现所有服务并获得所有符合条件的特征。在这些特征上,应设置通知/指示,然后与它们的来源配对(如果需要)。

示例代码:

device.establishConnection(false)
        .flatMap(connection -> connection.discoverServices()
                .map(RxBleDeviceServices::getBluetoothGattServices) // get them
                .flatMapObservable(Observable::fromIterable) // map to individual services
                .map(BluetoothGattService::getCharacteristics) // for each service take all characteristics
                .flatMap(Observable::fromIterable) // map to individual characteristic)
                .filter(characteristic -> (characteristic.getProperties() & (BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_INDICATE)) != 0) // consider only characteristics that have indicate or notify property
                .flatMap(characteristic -> {
                    NotificationSetupper notificationSetupper;
                    if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
                        notificationSetupper = setupNotifications(characteristic); // if supports notifications
                    } else {
                        notificationSetupper = setupIndications(characteristic); // else indications
                    }
                    return notificationSetupper.setupOn(connection);
                })
        )
        .subscribe(
                pair -> {
                    BluetoothGattCharacteristic characteristic = pair.first;
                    byte[] value = pair.second;
                    // do your thing with the emissions
                },
                throwable -> {
                    // log potential errors
                }
        );

助手在哪里

interface NotificationSetupper {

    Observable<Pair<BluetoothGattCharacteristic, byte[]>> setupOn(RxBleConnection connection);
}

static NotificationSetupper setupNotifications(BluetoothGattCharacteristic characteristic) {
    return connection -> connection.setupNotification(characteristic, getModeFor(characteristic))
            .compose(pairNotificationsWith(characteristic));
}

static NotificationSetupper setupIndications(BluetoothGattCharacteristic characteristic) {
    return connection -> connection.setupIndication(characteristic, getModeFor(characteristic))
            .compose(pairNotificationsWith(characteristic));
}

static NotificationSetupMode getModeFor(BluetoothGattCharacteristic characteristic) { // a different mode is needed if a characteristic has no Client Characteristic Configuration Descriptor
    UUID clientCharacteristicConfigurationDescriptorUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
    return characteristic.getDescriptor(clientCharacteristicConfigurationDescriptorUuid) != null ? NotificationSetupMode.DEFAULT : NotificationSetupMode.COMPAT;
}

static ObservableTransformer<Observable<byte[]>, Pair<BluetoothGattCharacteristic, byte[]>> pairNotificationsWith(BluetoothGattCharacteristic characteristic) { // to distinguish the source of notification we need to pair the value with the source
    return upstream -> upstream.flatMap(it -> it).map(bytes -> Pair.create(characteristic, bytes));
}
相关问题