Polidea RxAndroidBle启用通知

时间:2018-08-13 14:24:08

标签: android bluetooth-lowenergy rxandroidble

我非常需要这样做才能在我的应用程序中继续进行操作。

我对Android BLE以及使用多年非常熟悉。

我具有以下代码来启用通知,并且它与我的外围设备已经使用了多年。启用通知后,将使用“ OK_N1”调用onCharacteristicChanged()方法。

private void enableNotification(String serviceUUID, String characteristicUUID) {
    if (bluetoothGatt == null) {
        return;
    }
    BluetoothGattService service = bluetoothGatt.getService(UUID.fromString(serviceUUID));
    if (service == null) {
        return;
    }
    BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(characteristicUUID));

    bluetoothGatt.setCharacteristicNotification(characteristic, true);
    enableDescriptor(characteristic);
}

private void enableDescriptor(BluetoothGattCharacteristic bluetoothGattCharacteristic) {
    if (bluetoothGatt == null) {
        return;
    }
    BluetoothGattDescriptor descriptor = bluetoothGattCharacteristic.getDescriptor(
            UUID.fromString(PodsServiceCharacteristics.CLIENT_CHARACTERISTIC_CONFIG));
    if (descriptor == null)
        return;
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    bluetoothGatt.writeDescriptor(descriptor);
}

现在,我将Polidea RxAndroidble(1.7.0版)与RxJava2结合使用使事情变得简单。

我在Polidea的RxAndroidBle中无法使用以下代码。

public void enableNotifications(@NotNull String[] characteristics) {
    if (isConnected()) {
        mNotificationSubscriber = mRxBleConnection.setupNotification(UUID.fromString(characteristics[0]))
                .doOnNext(notificationObservable -> notificationHasBeenSetUp())
                .flatMap(notificationObservable -> notificationObservable)
                .subscribe(this::onNotificationReceived, this::onNotificationSetupFailure);
    }
}

private void onNotificationReceived(byte[] bytes) {
    Log.i(TAG, "onNotificationReceived");
}

private void onNotificationSetupFailure(Throwable throwable) {
    Log.i(TAG, "onNotificationSetupFailure" + throwable.getMessage());
}

private void notificationHasBeenSetUp() {
    Log.i(TAG, "notificationHasBeenSetUp");
}

notificationHasBeenSetUp()被调用,但onNotificationReceived()没有被调用,我得到了“ OK_N1”字节

1 个答案:

答案 0 :(得分:0)

可能是因为外围设备在设置Client Characteristic Configuration Descriptor之后立即发送了通知。

默认情况下,RxAndroidBle会在发出Observable<byte[]>之前完全设置通知,即必须在发出之前成功编写CCC描述符。

为了不错过任何“早期”排放,可以利用NotificationSetupMode.COMPAT,其中库不处理编写CCC描述符*。

(...)

mNotificationSubscriber = mRxBleConnection.discoverServices()
        .flatMap(rxBleDeviceServices -> rxBleDeviceServices.getCharacteristic(characteristicUuid))
        .flatMapObservable(bluetoothGattCharacteristic -> {
            BluetoothGattDescriptor cccDescriptor = bluetoothGattCharacteristic.getDescriptor(PodsServiceCharacteristics.CLIENT_CHARACTERISTIC_CONFIG);
            Completable enableNotificationCompletable = mRxBleConnection.writeDescriptor(cccDescriptor, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            Completable disableNotificationCompletable = mRxBleConnection.writeDescriptor(cccDescriptor, BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE).onErrorComplete();
            return mRxBleConnection.setupNotification(bluetoothGattCharacteristic, NotificationSetupMode.COMPAT)
                    .doOnNext(notificationObservable -> notificationHasBeenSetUp())
                    .flatMap(notificationObservable -> notificationObservable)
                    .mergeWith(enableNotificationCompletable)
                    .doOnDispose(disableNotificationCompletable::subscribe) // fire and forget
                    .share(); // this can be omitted but I put it here in case the resulting `Observable<byte[]>` would be shared among multiple subscribers
        })
        .subscribe(this::onNotificationReceived, this::onNotificationSetupFailure);

(...)

我认为由于这显然是很普遍的情况,它将在某些时候由图书馆处理。

* NotificationSetupMode.COMPAT主要是针对不遵循BLE规范且没有CCC描述符但仍将始终发送通知的BLE外围设备引入的。