From 7cc17240b3063272d04eed26499dadd0129bfc07 Mon Sep 17 00:00:00 2001 From: Rob Holmes Date: Thu, 2 Feb 2017 14:55:48 +0000 Subject: [PATCH 1/3] Added connection state observable --- .../rxbluetooth/ConnectionStateEvent.java | 80 +++++++++++++++++++ .../ivbaranov/rxbluetooth/RxBluetooth.java | 38 +++++++++ 2 files changed, 118 insertions(+) create mode 100644 rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java diff --git a/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java b/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java new file mode 100644 index 0000000..7131f57 --- /dev/null +++ b/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015 Ivan Baranov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.github.ivbaranov.rxbluetooth; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; + +/** + * Event container class. Contains connection state (whether the device is disconnected, connecting, connected, + * or disconnecting), previous connection state, and {@link BluetoothDevice}. + * + * Possible state values are: + * {@link BluetoothAdapter#STATE_DISCONNECTED}, + * {@link BluetoothAdapter#STATE_CONNECTING}, + * {@link BluetoothAdapter#STATE_CONNECTED}, + * {@link BluetoothAdapter#STATE_DISCONNECTING} + */ +public class ConnectionStateEvent { + + private int mState; + private int mPreviousState; + private BluetoothDevice mBluetoothDevice; + + public ConnectionStateEvent(int state, int previousState, BluetoothDevice bluetoothDevice) { + mState = state; + mPreviousState = previousState; + mBluetoothDevice = bluetoothDevice; + } + + public int getState() { + return mState; + } + + public int getPreviousState() { + return mState; + } + + public BluetoothDevice getBluetoothDevice() { + return mBluetoothDevice; + } + + @Override public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ConnectionStateEvent that = (ConnectionStateEvent) o; + + if (mState != that.mState) return false; + return !(mBluetoothDevice != null ? !mBluetoothDevice.equals(that.mBluetoothDevice) + : that.mBluetoothDevice != null); + } + + @Override public int hashCode() { + int result = mState; + result = 31 * result + mPreviousState; + result = 31 * result + (mBluetoothDevice != null ? mBluetoothDevice.hashCode() : 0); + return result; + } + + @Override public String toString() { + return "ConnectionStateEvent{" + + "mState=" + mState + + ", mPreviousState=" + mPreviousState + + ", mBluetoothDevice=" + mBluetoothDevice + + '}'; + } +} 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 8dad3ac..98f88b8 100644 --- a/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/RxBluetooth.java +++ b/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/RxBluetooth.java @@ -352,6 +352,44 @@ public void closeProfileProxy(int profile, BluetoothProfile proxy) { mBluetoothAdapter.closeProfileProxy(profile, proxy); } + /** + * Observes connection state of devices. + * + * @return RxJava Observable with {@link ConnectionStateEvent} + */ + public Observable observeConnectionState() { + final IntentFilter filter = new IntentFilter(); + filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); + + return Observable.defer(new Func0>() { + @Override public Observable call() { + + return Observable.create(new Observable.OnSubscribe() { + + @Override public void call(final Subscriber subscriber) { + 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); + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + + subscriber.onNext(new ConnectionStateEvent(status, previousStatus, device)); + } + }; + + context.registerReceiver(receiver, filter); + + subscriber.add(unsubscribeInUiThread(new Action0() { + @Override public void call() { + context.unregisterReceiver(receiver); + } + })); + } + }); + } + }); + } + /** * Opens {@link BluetoothServerSocket}, listens for a single connection request, releases socket * and returns a connected {@link BluetoothSocket} on successful connection. Notifies observers From b7f53915a0358e04b3d889cecaf96ad3cb1482ed Mon Sep 17 00:00:00 2001 From: Rob Holmes Date: Thu, 2 Feb 2017 15:12:49 +0000 Subject: [PATCH 2/3] Added docs for observeConnectionState --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index 3d57165..e422e38 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,42 @@ Clients should close profile proxy when they are no longer using the proxy obtai rxBluetooth.closeProfileProxy(int profile, BluetoothProfile proxy); ``` +##### Observing device state + +To observe the current device state, you can receive the `ConnectionStateEvent` which provides the state, previous state, and `BluetoothDevice`. + +```java +rxBluetooth.observeConnectionState() + .observeOn(AndroidSchedulers.mainThread()) + .subscribeOn(Schedulers.computation()) + .subscribe(new Action1() { + @Override public void call(ConnectionStateEvent event) { + switch (event.getState()) { + case BluetoothAdapter.STATE_DISCONNECTED: + // device disconnected + break; + case BluetoothAdapter.STATE_CONNECTING: + // device connecting + break; + case BluetoothAdapter.STATE_CONNECTED: + // device connected + break; + case BluetoothAdapter.STATE_DISCONNECTING: + // device disconnecting + break; + } + } + }); +``` + +Possible states are: +```java +BluetoothAdapter.STATE_DISCONNECTED +BluetoothAdapter.STATE_CONNECTING +BluetoothAdapter.STATE_CONNECTED +BluetoothAdapter.STATE_DISCONNECTING +``` + #### Read and Write with BluetoothSocket After creating a connection to the device, you can use `BluetoothConnection` class to read and write with its socket. From 7bc13cc324a4cb40acced138810ca674ebedde74 Mon Sep 17 00:00:00 2001 From: Rob Holmes Date: Thu, 2 Feb 2017 15:34:39 +0000 Subject: [PATCH 3/3] Added missing equality check on previous state --- .../com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java | 1 + 1 file changed, 1 insertion(+) diff --git a/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java b/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java index 7131f57..e780790 100644 --- a/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java +++ b/rxbluetooth/src/main/java/com/github/ivbaranov/rxbluetooth/ConnectionStateEvent.java @@ -59,6 +59,7 @@ public BluetoothDevice getBluetoothDevice() { ConnectionStateEvent that = (ConnectionStateEvent) o; if (mState != that.mState) return false; + if (mPreviousState != that.mPreviousState) return false; return !(mBluetoothDevice != null ? !mBluetoothDevice.equals(that.mBluetoothDevice) : that.mBluetoothDevice != null); }