7

私はBluetooth Low Energyに関する特定の要件を持つAndroidアプリケーションを構築しています。RxAndroidBleは持続的な接続を維持+書き込み/通知処理

書き込み専用の特性に書き込む必要があり、別の通知特性で応答を受け取る必要があります。多くの多くのアクティビティでそれを行う必要があります。第1の特性に関する要求を送信し、第2の特性に対する応答を待ってから別の要求に進むRx方法はありますか?

また、RxAndroidBleのインスタンスを共有するために、私はObservablesを公開するBleManager Singletonを実行することを考えました。私はPresenterで簡単にそれらを購読できます。私はちょうど各活動のための接続論理をコピーし、(理想的に)永続的な接続を持っていることを避けたいと思う。このようにして、私はconnectionObservableを公開して購読することしかできませんでしたので、簡単に書き込み要求を送信して通知を受け取ることができますが、これを行うより良い方法があると確信しています。

これは私が今のところ持っているものです。

@Singleton 
public class BleManager { 

    private PublishSubject<Void> disconnectTriggerSubject = PublishSubject.create(); 
    private Observable<RxBleConnection> connectionObservable; 
    private boolean isConnected; 

    private final UUID CTRL_FROM_BRIDGE_UUID = UUID.fromString("someUUID"); 
    private final UUID BLE_WRITE_CHARACTERISTIC_UUID = UUID.fromString("someOtherUUID"); 

    private final RxBleClient bleClient; 
    private String mMacAddress; 
    private final Context context; 
    private RxBleDevice bleDevice; 

    @Inject 
    public BleManager(Context context, RxBleClient client) { 
    Timber.d("Constructing BleManager and injecting members"); 
    this.context = context; 
    this.bleClient = client; 
    } 

    public void setMacAddress(String mMacAddress) { 
    this.mMacAddress = mMacAddress; 

    // Set the associated device on MacAddress change 
    bleDevice = bleClient.getBleDevice(this.mMacAddress); 
    } 

    public String getMacAddress() { 
    return mMacAddress; 
    } 

    public RxBleDevice getBleDevice() { 
    Preconditions.checkNotNull(mMacAddress); 
    return bleClient.getBleDevice(mMacAddress); 
    } 

    public Observable<RxBleScanResult> getScanSubscription() { 
    Preconditions.checkNotNull(context); 
    Preconditions.checkNotNull(bleClient); 

    return bleClient.scanBleDevices().distinct(); 
    } 

    public Observable<RxBleConnection> getConnectionSubscription() { 
    Preconditions.checkNotNull(context); 
    Preconditions.checkNotNull(bleDevice); 

    if (connectionObservable == null) { 
     connectionObservable = bleDevice.establishConnection(context, false) 
             .takeUntil(disconnectTriggerSubject) 
             .observeOn(AndroidSchedulers.mainThread()) 
             .doOnUnsubscribe(this::clearSubscription) 
             .compose(new ConnectionSharingAdapter()); 
    } 

    return connectionObservable; 
    } 

    public Observable<byte[]> setupListeners() { 
    return connectionObservable.flatMap(rxBleConnection -> rxBleConnection.setupNotification(CTRL_FROM_BRIDGE_UUID)) 
           .doOnNext(notificationObservable -> Timber.d("Notification Setup")) 
           .flatMap(notificationObservable -> notificationObservable) 
           .observeOn(AndroidSchedulers.mainThread()); 
    } 

    private void triggerDisconnect() { 
    disconnectTriggerSubject.onNext(null); 
    } 


    public Observable<byte[]> writeBytes(byte[] bytes) { 
    return connectionObservable.flatMap(rxBleConnection -> rxBleConnection.writeCharacteristic(
     BLE_WRITE_CHARACTERISTIC_UUID, 
     bytes)).observeOn(AndroidSchedulers.mainThread()); 
    } 

    private boolean isConnected() { 
    return bleDevice.getConnectionState() == RxBleConnection.RxBleConnectionState.CONNECTED; 
    } 

    /** 
    * Will update the UI with the current state of the Ble Connection 
    */ 
    private void registerConnectionStateChange() { 
    bleDevice.observeConnectionStateChanges().observeOn(AndroidSchedulers.mainThread()).subscribe(connectionState -> { 
     isConnected = connectionState.equals(RxBleConnection.RxBleConnectionState.CONNECTED); 
    }); 
    } 

    private void clearSubscription() { 
    connectionObservable = null; 
    } 

} 

答えて

4

私はあなたのユースケースについて少し考えています。同じ接続を共有すると、アプリケーションに状態を導入することになります。これには状態処理が必要なため、純粋に反応的であることは不可能です(少なくとも、どのように考えているかはわかりません)。

私は接続を確立し、シリアル化されたBLEデバイスへの書き込み通知送信を行うことに焦点を合わせました。

これは、フロー全体が1か所に記述されているためわかりやすいアプローチだと思います。ステートフル(書き込み要求と応答待ち)の通信部分はシリアル化されており、disconnect()呼び出しまで接続を維持する可能性があります。

接続が確立される前に送信が異なるフローの副作用に頼って、writeData()を呼び出すという欠点があります。このシナリオの処理を追加することは問題ではありませんが通知設定は返されたObservableを決して完了しません状態をチェックして

よろしくお願いします。

+0

私はあなたの解決策を試してみましょう。私はRxの世界に新しい人で、まだ学んでいるので、本当に感謝しています! –

+3

提案されたソリューションを試しましたか?それは意図どおりに機能しましたか? –

関連する問題