Skip to content

Commit

Permalink
Merge pull request #51 from vanniktech/connectAsClient
Browse files Browse the repository at this point in the history
Add RxBluetooth#connectAsClient with RFCOMM channel id.
  • Loading branch information
IvBaranov authored Nov 13, 2018
2 parents 5afc6ba + b8c32e1 commit ce79eae
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import static android.location.LocationManager.GPS_PROVIDER;
import static android.location.LocationManager.NETWORK_PROVIDER;
import static android.os.Build.VERSION.SDK_INT;
import static com.github.ivbaranov.rxbluetooth.Utils.createRfcommSocket;

/**
* Enables clients to listen to bluetooth events using RxJava Observables.
Expand Down Expand Up @@ -479,7 +480,7 @@ public Observable<BondStateEvent> observeBondState() {

/**
* Create connection to {@link BluetoothDevice} and returns a connected {@link BluetoothSocket}
* on successful connection. Notifies observers with {@link IOException} {@code onError()}.
* on successful connection. Notifies observers with {@link IOException} via {@code onError()}.
*
* @param bluetoothDevice bluetooth device to connect
* @param uuid uuid for SDP record
Expand Down Expand Up @@ -520,7 +521,7 @@ public Single<BluetoothSocket> connectAsServer(final String name, final UUID uui

/**
* Create connection to {@link BluetoothDevice} and returns a connected {@link BluetoothSocket}
* on successful connection. Notifies observers with {@link IOException} {@code onError()}.
* on successful connection. Notifies observers with {@link IOException} via {@code onError()}.
*
* @param bluetoothDevice bluetooth device to connect
* @param uuid uuid for SDP record
Expand All @@ -536,7 +537,42 @@ public Single<BluetoothSocket> connectAsClient(final BluetoothDevice bluetoothDe
bluetoothSocket.connect();
emitter.onSuccess(bluetoothSocket);
} catch (IOException e) {
if(bluetoothSocket != null) {
if (bluetoothSocket != null) {
try {
bluetoothSocket.close();
} catch (IOException suppressed) {
if (SDK_INT >= 19) {
e.addSuppressed(suppressed);
}
}
}
emitter.onError(e);
}
}
});
}

/**
* Create connection to {@link BluetoothDevice} via createRfcommSocket and returns a connected {@link BluetoothSocket}
* on successful connection.
* Note: createRfcommSocket is not public API and hence this might break in the future.
* Notifies observers with {@link IOException} or any reflection related exception via {@code onError()}.
*
* @param bluetoothDevice bluetooth device to connect
* @param channel RFCOMM channel to connect to
* @return Single with connected {@link BluetoothSocket} on successful connection
*/
public Single<BluetoothSocket> connectAsClient(final BluetoothDevice bluetoothDevice,
final int channel) {
return Single.create(new SingleOnSubscribe<BluetoothSocket>() {
@Override public void subscribe(@NonNull SingleEmitter<BluetoothSocket> emitter) {
BluetoothSocket bluetoothSocket = null;
try {
bluetoothSocket = createRfcommSocket(bluetoothDevice, channel);
bluetoothSocket.connect();
emitter.onSuccess(bluetoothSocket);
} catch (IOException e) {
if (bluetoothSocket != null) {
try {
bluetoothSocket.close();
} catch (IOException suppressed) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.github.ivbaranov.rxbluetooth;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

final class Utils {
static void close(Closeable closeable) {
static void close(final Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
Expand All @@ -14,6 +18,20 @@ static void close(Closeable closeable) {
}
}

@SuppressWarnings("unchecked") static BluetoothSocket createRfcommSocket(
final BluetoothDevice device, final int channel) {
try {
Method method = BluetoothDevice.class.getMethod("createRfcommSocket", Integer.TYPE);
return (BluetoothSocket) method.invoke(device, channel);
} catch (final NoSuchMethodException e) {
throw new UnsupportedOperationException(e);
} catch (final InvocationTargetException e) {
throw new UnsupportedOperationException(e);
} catch (final IllegalAccessException e) {
throw new UnsupportedOperationException(e);
}
}

private Utils() {
throw new AssertionError("No instances.");
}
Expand Down

0 comments on commit ce79eae

Please sign in to comment.