diff --git a/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/RxBluetooth.java b/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/RxBluetooth.java index c114dfc..dca866a 100644 --- a/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/RxBluetooth.java +++ b/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/RxBluetooth.java @@ -39,13 +39,14 @@ import io.reactivex.Observable; import io.reactivex.ObservableEmitter; import io.reactivex.ObservableOnSubscribe; -import io.reactivex.ObservableSource; +import io.reactivex.Single; +import io.reactivex.SingleEmitter; +import io.reactivex.SingleOnSubscribe; import io.reactivex.android.MainThreadDisposable; import io.reactivex.annotations.NonNull; import java.io.IOException; import java.util.Set; import java.util.UUID; -import java.util.concurrent.Callable; import static android.Manifest.permission.ACCESS_COARSE_LOCATION; import static android.location.LocationManager.GPS_PROVIDER; @@ -226,28 +227,24 @@ public void enableDiscoverability(Activity activity, int requestCode, int durati */ public Observable observeDevices() { final IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull final ObservableEmitter emitter) - throws Exception { - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(BluetoothDevice.ACTION_FOUND)) { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - emitter.onNext(device); - } - } - }; + return Observable.create(new ObservableOnSubscribe() { + @Override public void subscribe(@NonNull final ObservableEmitter emitter) + throws Exception { + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (action.equals(BluetoothDevice.ACTION_FOUND)) { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + emitter.onNext(device); + } + } + }; - context.registerReceiver(receiver, filter); + context.registerReceiver(receiver, filter); - emitter.setDisposable(new MainThreadDisposable() { - @Override protected void onDispose() { - context.unregisterReceiver(receiver); - } - }); + emitter.setDisposable(new MainThreadDisposable() { + @Override protected void onDispose() { + context.unregisterReceiver(receiver); } }); } @@ -265,24 +262,20 @@ public Observable observeDiscovery() { filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull final ObservableEmitter emitter) - throws Exception { - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - emitter.onNext(intent.getAction()); - } - }; + return Observable.create(new ObservableOnSubscribe() { + @Override public void subscribe(@NonNull final ObservableEmitter emitter) + throws Exception { + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + emitter.onNext(intent.getAction()); + } + }; - context.registerReceiver(receiver, filter); + context.registerReceiver(receiver, filter); - emitter.setDisposable(new MainThreadDisposable() { - @Override protected void onDispose() { - context.unregisterReceiver(receiver); - } - }); + emitter.setDisposable(new MainThreadDisposable() { + @Override protected void onDispose() { + context.unregisterReceiver(receiver); } }); } @@ -302,24 +295,20 @@ public Observable observeBluetoothState() { final IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull final ObservableEmitter emitter) - throws Exception { - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - emitter.onNext(bluetoothAdapter.getState()); - } - }; + return Observable.create(new ObservableOnSubscribe() { + @Override public void subscribe(@NonNull final ObservableEmitter emitter) + throws Exception { + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + emitter.onNext(bluetoothAdapter.getState()); + } + }; - context.registerReceiver(receiver, filter); + context.registerReceiver(receiver, filter); - emitter.setDisposable(new MainThreadDisposable() { - @Override protected void onDispose() { - context.unregisterReceiver(receiver); - } - }); + emitter.setDisposable(new MainThreadDisposable() { + @Override protected void onDispose() { + context.unregisterReceiver(receiver); } }); } @@ -338,24 +327,20 @@ public Observable observeScanMode() { final IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull final ObservableEmitter emitter) - throws Exception { - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - emitter.onNext(bluetoothAdapter.getScanMode()); - } - }; + return Observable.create(new ObservableOnSubscribe() { + @Override public void subscribe(@NonNull final ObservableEmitter emitter) + throws Exception { + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + emitter.onNext(bluetoothAdapter.getScanMode()); + } + }; - context.registerReceiver(receiver, filter); + context.registerReceiver(receiver, filter); - emitter.setDisposable(new MainThreadDisposable() { - @Override protected void onDispose() { - context.unregisterReceiver(receiver); - } - }); + emitter.setDisposable(new MainThreadDisposable() { + @Override protected void onDispose() { + context.unregisterReceiver(receiver); } }); } @@ -371,24 +356,20 @@ public Observable observeScanMode() { * @return RxJava Observable with {@link ServiceEvent} */ public Observable observeBluetoothProfile(final int bluetoothProfile) { - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull final ObservableEmitter emitter) - throws Exception { - if (!bluetoothAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() { - @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { - emitter.onNext(new ServiceEvent(ServiceEvent.State.CONNECTED, profile, proxy)); - } + return Observable.create(new ObservableOnSubscribe() { + @Override public void subscribe(@NonNull final ObservableEmitter emitter) + throws Exception { + if (!bluetoothAdapter.getProfileProxy(context, new BluetoothProfile.ServiceListener() { + @Override public void onServiceConnected(int profile, BluetoothProfile proxy) { + emitter.onNext(new ServiceEvent(ServiceEvent.State.CONNECTED, profile, proxy)); + } - @Override public void onServiceDisconnected(int profile) { - emitter.onNext(new ServiceEvent(ServiceEvent.State.DISCONNECTED, profile, null)); - } - }, bluetoothProfile)) { - emitter.onError(new GetProfileProxyException()); - } + @Override public void onServiceDisconnected(int profile) { + emitter.onNext(new ServiceEvent(ServiceEvent.State.DISCONNECTED, profile, null)); } - }); + }, bluetoothProfile)) { + emitter.onError(new GetProfileProxyException()); + } } }); } @@ -418,32 +399,28 @@ public Observable observeConnectionState() { final IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override - public void subscribe(@NonNull final ObservableEmitter emitter) - throws Exception { - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, + return Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(@NonNull final ObservableEmitter emitter) + throws Exception { + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + int status = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, + BluetoothAdapter.STATE_DISCONNECTED); + int previousStatus = + intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED); - int previousStatus = - intent.getIntExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, - BluetoothAdapter.STATE_DISCONNECTED); - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - emitter.onNext(new ConnectionStateEvent(status, previousStatus, device)); - } - }; + emitter.onNext(new ConnectionStateEvent(status, previousStatus, device)); + } + }; - context.registerReceiver(receiver, filter); + context.registerReceiver(receiver, filter); - emitter.setDisposable(new MainThreadDisposable() { - @Override protected void onDispose() { - context.unregisterReceiver(receiver); - } - }); + emitter.setDisposable(new MainThreadDisposable() { + @Override protected void onDispose() { + context.unregisterReceiver(receiver); } }); } @@ -459,30 +436,26 @@ public Observable observeBondState() { final IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED); - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull final ObservableEmitter emitter) - throws Exception { - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - int state = - intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); - int previousState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, - BluetoothDevice.BOND_NONE); - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - - emitter.onNext(new BondStateEvent(state, previousState, device)); - } - }; + return Observable.create(new ObservableOnSubscribe() { + @Override public void subscribe(@NonNull final ObservableEmitter emitter) + throws Exception { + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + int state = + intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE); + int previousState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, + BluetoothDevice.BOND_NONE); + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + + emitter.onNext(new BondStateEvent(state, previousState, device)); + } + }; - context.registerReceiver(receiver, filter); + context.registerReceiver(receiver, filter); - emitter.setDisposable(new MainThreadDisposable() { - @Override protected void onDispose() { - context.unregisterReceiver(receiver); - } - }); + emitter.setDisposable(new MainThreadDisposable() { + @Override protected void onDispose() { + context.unregisterReceiver(receiver); } }); } @@ -497,26 +470,49 @@ public Observable observeBondState() { * @param name service name for SDP record * @param uuid uuid for SDP record * @return observable with connected {@link BluetoothSocket} on successful connection + * @deprecated use {{@link #connectAsServer(String, UUID)}} instead */ - public Observable observeBluetoothSocket(final String name, final UUID uuid) { - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull ObservableEmitter emitter) - throws Exception { - try { - BluetoothServerSocket bluetoothServerSocket = - bluetoothAdapter.listenUsingRfcommWithServiceRecord(name, uuid); - try { - emitter.onNext(bluetoothServerSocket.accept()); - } finally { - bluetoothServerSocket.close(); - } - } catch(IOException e) { - emitter.onError(e); - } + @Deprecated public Observable observeBluetoothSocket(final String name, final UUID uuid) { + return connectAsServer(name, uuid).toObservable(); + } + + /** + * Create connection to {@link BluetoothDevice} and returns a connected {@link BluetoothSocket} + * on successful connection. Notifies observers with {@link IOException} {@code onError()}. + * + * @param bluetoothDevice bluetooth device to connect + * @param uuid uuid for SDP record + * @return observable with connected {@link BluetoothSocket} on successful connection + * @deprecated use {{@link #connectAsClient(BluetoothDevice, UUID)}} instead + */ + @Deprecated public Observable observeConnectDevice(final BluetoothDevice bluetoothDevice, + final UUID uuid) { + return connectAsClient(bluetoothDevice, uuid).toObservable(); + } + + /** + * Opens {@link BluetoothServerSocket}, listens for a single connection request, releases socket + * and returns a connected {@link BluetoothSocket} on successful connection. Notifies observers + * with {@link IOException} {@code onError()}. + * + * @param name service name for SDP record + * @param uuid uuid for SDP record + * @return Single with connected {@link BluetoothSocket} on successful connection + */ + public Single connectAsServer(final String name, final UUID uuid) { + return Single.create(new SingleOnSubscribe() { + @Override public void subscribe(@NonNull SingleEmitter emitter) { + try { + BluetoothServerSocket bluetoothServerSocket = + bluetoothAdapter.listenUsingRfcommWithServiceRecord(name, uuid); + try { + emitter.onSuccess(bluetoothServerSocket.accept()); + } finally { + bluetoothServerSocket.close(); } - }); + } catch(IOException e) { + emitter.onError(e); + } } }); } @@ -527,34 +523,29 @@ public Observable observeBluetoothSocket(final String name, fin * * @param bluetoothDevice bluetooth device to connect * @param uuid uuid for SDP record - * @return observable with connected {@link BluetoothSocket} on successful connection + * @return Single with connected {@link BluetoothSocket} on successful connection */ - public Observable observeConnectDevice(final BluetoothDevice bluetoothDevice, + public Single connectAsClient(final BluetoothDevice bluetoothDevice, final UUID uuid) { - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull ObservableEmitter emitter) - throws Exception { - BluetoothSocket bluetoothSocket = null; + return Single.create(new SingleOnSubscribe() { + @Override public void subscribe(@NonNull SingleEmitter emitter) { + BluetoothSocket bluetoothSocket = null; + try { + bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid); + bluetoothSocket.connect(); + emitter.onSuccess(bluetoothSocket); + } catch (IOException e) { + if(bluetoothSocket != null) { try { - bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid); - bluetoothSocket.connect(); - emitter.onNext(bluetoothSocket); - } catch (IOException e) { - if(bluetoothSocket != null) { - try { - bluetoothSocket.close(); - } catch (IOException suppressed) { - if (SDK_INT >= 19) { - e.addSuppressed(suppressed); - } - } + bluetoothSocket.close(); + } catch (IOException suppressed) { + if (SDK_INT >= 19) { + e.addSuppressed(suppressed); } - emitter.onError(e); } } - }); + emitter.onError(e); + } } }); } @@ -574,27 +565,23 @@ public Observable observeAclEvent() { filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED); - return Observable.defer(new Callable>() { - @Override public ObservableSource call() throws Exception { - return Observable.create(new ObservableOnSubscribe() { - @Override public void subscribe(@NonNull final ObservableEmitter emitter) - throws Exception { - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - - emitter.onNext(new AclEvent(action, device)); - } - }; + return Observable.create(new ObservableOnSubscribe() { + @Override public void subscribe(@NonNull final ObservableEmitter emitter) + throws Exception { + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - context.registerReceiver(receiver, filter); + emitter.onNext(new AclEvent(action, device)); + } + }; - emitter.setDisposable(new MainThreadDisposable() { - @Override protected void onDispose() { - context.unregisterReceiver(receiver); - } - }); + context.registerReceiver(receiver, filter); + + emitter.setDisposable(new MainThreadDisposable() { + @Override protected void onDispose() { + context.unregisterReceiver(receiver); } }); } @@ -613,31 +600,27 @@ public Observable observeFetchDeviceUuids(final BluetoothDevice bl final IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_UUID); - return Observable.defer(new Callable>() { - @Override public ObservableSource call() { - return Observable.create(new ObservableOnSubscribe() { - @Override - public void subscribe(@NonNull final ObservableEmitter emitter) { - final BroadcastReceiver receiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID); - emitter.onNext(uuids); - emitter.onComplete(); - } - }; - - context.registerReceiver(receiver, filter); - - emitter.setDisposable(new MainThreadDisposable() { - @Override - protected void onDispose() { - context.unregisterReceiver(receiver); - } - }); - - bluetoothDevice.fetchUuidsWithSdp(); - } + return Observable.create(new ObservableOnSubscribe() { + @Override + public void subscribe(@NonNull final ObservableEmitter emitter) { + final BroadcastReceiver receiver = new BroadcastReceiver() { + @Override public void onReceive(Context context, Intent intent) { + Parcelable[] uuids = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID); + emitter.onNext(uuids); + emitter.onComplete(); + } + }; + + context.registerReceiver(receiver, filter); + + emitter.setDisposable(new MainThreadDisposable() { + @Override + protected void onDispose() { + context.unregisterReceiver(receiver); + } }); + + bluetoothDevice.fetchUuidsWithSdp(); } }); }