0

RxAndroidBle を使用して予期しない動作を理解するのに苦労しています。

問題の簡単な形式は、特定のデバイスの 2 つの特性から順に通知を受信する必要があるということです。以下の例では、SERVICE_UUID をスキャンし、CHARACTERISTIC_FOO_UUID と CHARACTERISTIC_BAR_UUID の通知を (順番に) セットアップします。両方の特性からの応答に基づいて何かを行う必要があります --- 私の例では、byte[] をメンバー変数に格納するだけです。

私が抱えている問題は、最初の特性は報告されますが、2 番目の特性は報告されないことです。順番を入れ替えても、チェーンの最初の特性になります。以下にデバッグ出力を示します。これは、低レベル記述子の書き込みを含む両方に対して通知呼び出しが発生することを示していますが、何らかの理由で 2 番目のものは報告されません。(私が Observable を購読していると仮定します。)

RxAndroidBleなしでこれを機能させることができました。RxAndroidBle を採用したバージョンも 1 つありますが、これは動作しますが、ConnectionSharingAdapter といくつかのサブスクリプションを使用して別の方法でセットアップされています。以下の例は、よりクリーンなアプローチの試みですが、私が言ったように、うまくいかないようです。

rxBleClient.scanBleDevices(SERVICE_UUID)
    .first()
    .flatMap(rxBleScanResult -> {
        return Observable.just(rxBleScanResult.getBleDevice());
    })
    .flatMap(rxBleDevice -> {
        return rxBleDevice.establishConnection(context, IS_AUTO_CONNECT);
    })
    .flatMap(rxBleConnection -> 
        rxBleConnection.setupNotification(CHARACTERISTIC_FOO_UUID)
        .flatMap(observable -> observable)
        .flatMap(new Func1<byte[], Observable<RxBleConnection>>() {
            @Override
            public Observable<RxBleConnection> call(final byte[] notificationBytes) {
                mFooBytes = notificationBytes;
                return Observable.just(rxBleConnection);
            }
        })
    )
    .flatMap(rxBleConnection -> 
        rxBleConnection.setupNotification(CHARACTERISTIC_BAR_UUID)
        .flatMap(observable -> observable)
        .flatMap(new Func1<byte[], Observable<RxBleConnection>>() {
            @Override
            public Observable<RxBleConnection> call(final byte[] notificationBytes) {
                mBarBytes = notificationBytes;
                return Observable.just(rxBleConnection);
            }
        })
    )

ここに RxBle デバッグ出力があります --- 出力の「CHARACTERISTIC_FOO_UUID」で実際の uuid を編集しました。

12-22 12:13:43.322 12074-12074/com.foo.example D/RxBle#Radio:   QUEUED RxBleRadioOperationScan(217963087)
12-22 12:13:43.322 12074-12281/com.foo.example D/RxBle#Radio:  STARTED RxBleRadioOperationScan(217963087)
12-22 12:13:43.412 12074-12281/com.foo.example D/RxBle#Radio: FINISHED RxBleRadioOperationScan(217963087)
12-22 12:13:43.682 12074-12074/com.foo.example D/RxBle#Radio:   QUEUED RxBleRadioOperationConnect(37012551)
12-22 12:13:43.682 12074-12281/com.foo.example D/RxBle#Radio:  STARTED RxBleRadioOperationConnect(37012551)
12-22 12:13:44.052 12074-12085/com.foo.example D/RxBle#BluetoothGatt: onConnectionStateChange newState=2 status=0
12-22 12:13:44.092 12074-12558/com.foo.example D/RxBle#Radio:   QUEUED RxBleRadioOperationServicesDiscover(72789039)
12-22 12:13:44.092 12074-12281/com.foo.example D/RxBle#Radio: FINISHED RxBleRadioOperationConnect(37012551)
12-22 12:13:44.092 12074-12281/com.foo.example D/RxBle#Radio:  STARTED RxBleRadioOperationServicesDiscover(72789039)
12-22 12:13:45.232 12074-12086/com.foo.example D/RxBle#BluetoothGatt: onServicesDiscovered status=0
12-22 12:13:45.262 12074-12558/com.foo.example D/RxBle#Radio:   QUEUED RxBleRadioOperationDescriptorWrite(8700606)
12-22 12:13:45.262 12074-12281/com.foo.example D/RxBle#Radio: FINISHED RxBleRadioOperationServicesDiscover(72789039)
12-22 12:13:45.262 12074-12281/com.foo.example D/RxBle#Radio:  STARTED RxBleRadioOperationDescriptorWrite(8700606)
12-22 12:13:45.342 12074-12085/com.foo.example D/RxBle#BluetoothGatt: onDescriptorWrite descriptor=00002902-0000-1000-8000-00805f9b34fb status=0
12-22 12:13:45.362 12074-12281/com.foo.example D/RxBle#Radio: FINISHED RxBleRadioOperationDescriptorWrite(8700606)
12-22 12:13:46.172 12074-12086/com.foo.example D/RxBle#BluetoothGatt: onCharacteristicChanged characteristic=CHARACTERISTIC_FOO_UUID
12-22 12:13:46.192 12074-12558/com.foo.example D/RxBle#Radio:   QUEUED RxBleRadioOperationDescriptorWrite(179103302)
12-22 12:13:46.192 12074-12281/com.foo.example D/RxBle#Radio:  STARTED RxBleRadioOperationDescriptorWrite(179103302)
12-22 12:13:46.272 12074-12201/com.foo.example D/RxBle#BluetoothGatt: onDescriptorWrite descriptor=00002902-0000-1000-8000-00805f9b34fb status=0
12-22 12:13:46.272 12074-12281/com.foo.example D/RxBle#Radio: FINISHED RxBleRadioOperationDescriptorWrite(179103302)

以下は、機能するが複数のサブスクリプションと ConnectionSharingAdapter を使用する RxAndroidBle を使用するバージョンの簡単な例です。両方のバージョンで、Observable は別の場所にサブスクライブされるため、複数のサブスクリプション (ここでは CompositeSubscription、別の場所では他のサブスクリプション) の簿記をすべて回避しようとしています。問題を抱えている上記のアプローチは、より機能的なようです。私の実際のアプリケーションでは、私がやっていることはもっと複雑なので、上記のバージョンは実際には理解しやすくなっています。

CompositeSubscription bleConnectionSubscriptions = new CompositeSubscription();

Observable<RxBleConnection> bleConnectionObservable =
    bleConnectionObservable = bleDevice.establishConnection(context, IS_AUTO_CONNECT)
        .compose(new ConnectionSharingAdapter());

Subscription subscription =
    bleConnectionObservable
        .flatMap(rxBleConnection ->
                 rxBleConnection.setupNotification(CHARACTERISTIC_FOO_INGREDIENTS))
        .flatMap(observable -> observable)
        .subscribe(notificationBytes -> mFooBytes = notificationBytes);

bleConnectionSubscriptions.add(subscription);

subscription =
    bleConnectionObservable
        .flatMap(rxBleConnection ->
                 rxBleConnection.setupNotification(CHARACTERISTIC_BAR_INGREDIENTS))
        .flatMap(observable -> observable)
        .subscribe(notificationBytes -> mBarBytes = notificationBytes);

bleConnectionSubscriptions.add(subscription);
4

1 に答える 1

1

ログでわかるように、両方の通知が適切に設定されていますが、2 番目の通知は値を受け取りません。疑わしいのは、通知が設定される前に BAR 値が発行されることです。

以下のようなコードを使用して、接続の最初に両方の通知を設定できます。

rxBleClient.scanBleDevices(SERVICE_UUID)
        .first() // subscribe to the first device that is available...
        .flatMap(rxBleScanResult -> rxBleScanResult.getBleDevice().establishConnection(context, IS_AUTO_CONNECT)) // ...establish the connection...
        .flatMap(rxBleConnection -> Observable.combineLatest( // ...when connection is established we combine latest results from...
                rxBleConnection.setupNotification(CHARACTERISTIC_FOO_INGREDIENTS) // ...setup notification on FOO...
                        .flatMap(observable -> observable) // ...flatMap it to values...
                        .first(), // ...take the first value so the notification will be disposed...
                rxBleConnection.setupNotification(CHARACTERISTIC_BAR_INGREDIENTS) // ...setup notification on BAR...
                        .flatMap(observable -> observable) // ...flatMap it to values...
                        .first(), // ...take the first value so the notification will be disposed...
                ((fooBytes, barBytes) -> {
                    mFooBytes = fooBytes; 
                    mBarBytes = barBytes;
                    return true; // return whatever
                })
        ))
        .first(); // after the first returned value the connection will be disconnected
于 2016-12-23T13:06:52.937 に答える