package info.izumin.android.bletia.rx; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattDescriptor; import android.content.Context; import java.util.HashMap; import java.util.Map; import java.util.UUID; import info.izumin.android.bletia.core.AbstractBletia; import info.izumin.android.bletia.core.BletiaException; import info.izumin.android.bletia.rx.action.RxConnectAction; import info.izumin.android.bletia.rx.action.RxDisableNotificationAction; import info.izumin.android.bletia.rx.action.RxDisconnectAction; import info.izumin.android.bletia.rx.action.RxDiscoverServicesAction; import info.izumin.android.bletia.rx.action.RxEnableNotificationAction; import info.izumin.android.bletia.rx.action.RxReadCharacteristicAction; import info.izumin.android.bletia.rx.action.RxReadDescriptorAction; import info.izumin.android.bletia.rx.action.RxReadRemoteRssiAction; import info.izumin.android.bletia.rx.action.RxWriteCharacteristicAction; import info.izumin.android.bletia.rx.action.RxWriteDescriptorAction; import rx.Observable; import rx.functions.Action0; import rx.functions.Action1; import rx.subjects.PublishSubject; /** * Created by izumin on 11/15/15. */ public class RxBletia extends AbstractBletia { public static final String TAG = RxBletia.class.getSimpleName(); private final Map<UUID, RxEnableNotificationAction> mEnabledNotificationList; private final PublishSubject<BletiaException> mExceptionSubject; public RxBletia(Context context) { super(context); setSubListener(mListener); mEnabledNotificationList = new HashMap<>(); mExceptionSubject = PublishSubject.create(); } public Observable<Void> connect(BluetoothDevice device) { return execute(new RxConnectAction(device, getStateContainer())); } public Observable<Void> disconnect() { return execute(new RxDisconnectAction(getStateContainer())); } public Observable<Void> discoverServices() { return execute(new RxDiscoverServicesAction(getStateContainer())); } public Observable<BluetoothGattCharacteristic> writeCharacteristic(BluetoothGattCharacteristic characteristic) { return execute(new RxWriteCharacteristicAction(characteristic)); } public Observable<BluetoothGattCharacteristic> readCharacteristic(BluetoothGattCharacteristic characteristic) { return execute(new RxReadCharacteristicAction(characteristic)); } public Observable<BluetoothGattDescriptor> writeDescriptor(BluetoothGattDescriptor descriptor) { return execute(new RxWriteDescriptorAction(descriptor)); } public Observable<BluetoothGattDescriptor> readDescriptor(BluetoothGattDescriptor descriptor) { return execute(new RxReadDescriptorAction(descriptor)); } public Observable<BluetoothGattCharacteristic> enableNotification(BluetoothGattCharacteristic characteristic, boolean enabled) { return enabled ? enableNotification(characteristic) : disableNotification(characteristic); } public Observable<BluetoothGattCharacteristic> enableNotification(final BluetoothGattCharacteristic characteristic) { final UUID uuid = characteristic.getUuid(); if (mEnabledNotificationList.containsKey(uuid)) { return mEnabledNotificationList.get(uuid).getResolver(); } final RxEnableNotificationAction action = new RxEnableNotificationAction(characteristic); mEnabledNotificationList.put(characteristic.getUuid(), action); return execute(action).doOnUnsubscribe(new Action0() { @Override public void call() { mEnabledNotificationList.remove(uuid); } }); } public Observable<BluetoothGattCharacteristic> disableNotification(BluetoothGattCharacteristic characteristic) { return execute(new RxDisableNotificationAction(characteristic)) .doOnNext(new Action1<BluetoothGattCharacteristic>() { @Override public void call(BluetoothGattCharacteristic characteristic) { mEnabledNotificationList.remove(characteristic.getUuid()); } }); } public Observable<Integer> readRemoteRssi() { return execute(new RxReadRemoteRssiAction()); } public Observable<BletiaException> observeError() { return mExceptionSubject; } private final BleEventListener mListener = new BleEventListener() { @Override public void onCharacteristicChanged(final BluetoothGattCharacteristic characteristic) { final UUID uuid = characteristic.getUuid(); if (mEnabledNotificationList.containsKey(uuid)) { mEnabledNotificationList.get(uuid).resolve(characteristic); } } @Override public void onError(BletiaException exception) { mExceptionSubject.onNext(exception); } }; }