Bluetooth Low Energy に関する特定の要件を持つ Android アプリケーションを構築しています。
書き込み専用の特性に書き込み、別の通知特性で応答を受け取る必要があり、非常に多くのアクティビティでそれを行う必要があります。最初の特性で要求を送信し、2 番目の特性で応答を待ってから、別の要求に進む Rx の方法はありますか?
また、RxAndroidBle のインスタンスを共有するために、Observable を公開する BleManager シングルトンを実行することを考えたので、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;
}
}