VincentMasselis / Rxbluetoothkotlin
Programming Languages
Projects that are alternatives of or similar to Rxbluetoothkotlin
RxBluetoothKotlin
Android + BLE + Kotlin + RxJava3
Bluetooth Low Energy on Android made easy with RxJava.
Made with love at the Equisense HQ. This library is used in our Equisense app since years.
Looking for BLE with Coroutines instead of RxJava ? Take a look at the LouisCAD's implementation.
⚠️ Android 10 permissions changes ⚠️
Starting from Android API 29, the coarse location permission is not required anymore, instead of this, you have to use the FINE permission location to scan over the bluetooth low energy. Before upgrading targetSdkVersion
to 29 in your app, check your requestPermission
calls according to this new permission.
Because of this change, RxBluetoothKotlin was updated to fire the NeedLocationPermission
exception at the right moment when the fine location permission is missing starting from the release 1.2.2
.
If you're targeting Android API 28 and less, the last supported release is 1.2.1, if you're targeting API 29 or more, you should use the last version of RxBluetoothKotlin.
TL/DR
implementation 'com.vincentmasselis.rxbluetoothkotlin:rxbluetoothkotlin-core:1.3.0'
// Add this to use the scanner
implementation 'no.nordicsemi.android.support.v18:scanner:1.4.3'
// RxBluetoothKotlin doesn't provides the RxJava dependecy, you have to add it yourself:
implementation 'io.reactivex.rxjava3:rxjava:3.0.6'
Scan
val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
bluetoothManager.rxScan()
.subscribe { scanResult ->
}
Connect
bluetoothDevice.connectRxGatt()
.flatMapMaybe { gatt -> gatt.whenConnectionIsReady().map { gatt } }
.subsribe { rxBluetoothGatt ->
}
Read
rxBluetoothGatt.read(characteristic)
.subscribe { byteArray ->
}
Write
rxBluetoothGatt.write(characteristic, byteArray)
.subscribe { _ ->
}
Listen
rxBluetoothGatt.enableNotification(characteristic)
.flatMapPublisher { listenChanges(characteristic) }
.subscribe { byteArray ->
}
Disconnect
rxBluetoothGatt.disconnect().subscribe()
Requirements
- Min target API 18
- A manifest with
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
and<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
- The user permission to access to the fine Location
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), PERMISSION_CODE_FINE_LOCATION)
- A turned on bluetooth chip
(context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager).adapter.isEnabled
Logging
When scanning with rxScan()
or connecting with connectRxGatt()
, you can set the logger
parameter. By setting it, RxBluetoothKotlin will produce a log for every bluetooth input, output, starting scan, error thrown, etc.. I recommend to set it for debugging purproses and/or if you're not familiar with the Android BLE API. It could helps you a lot to understand what's going on between your app and the Bluetooth Low Energy device.
Error management
Interact with Bluetooth Low Energy devices on Android is hard. The BLE specs uses unfamiliars concepts, the BLE API from Android could fails at any moment and some exceptions are silent. Because of this, a basic method like write(BluetoothGattCharacteristic)
could fails for 5 differents reasons. It becomes harder if you are chaining this call with other calls, this sum up to a thrown exception when it's impossible to known which call fails and why.
For this reason, every public method from this library is documented with every exceptions which could be fired and most of the exception are unique. For example: write(BluetoothGattCharacteristic)
could fire:
- Unique
CharacteristicWriteDeviceDisconnected
if the device disconnects while writing - Unique
CannotInitializeCharacteristicWrite
if the Android API returnedfalse
when callingwriteCharacteristic
- Unique
CharacteristicWriteFailed
if the characteristic could not be written -
BluetoothIsTurnedOff
if bluetooth...... is turned off 🤷🏻♀️ -
BluetoothTimeout
if writing takes more than 1 minute
All the 3 uniques exceptions are containing the required data to understand why it failed. For example CharacteristicWriteDeviceDisconnected
has 5 fields, bluetoothDevice
, status
, service
, characteristic
and value
, all of theses fields should helps you to understand what's going on.
Demo app
If you're not familiar with the Bluetooth Low Energy API or if you want to try this lib, you can build and run the demo app from this repo.
Decorator pattern
⚠ Before reading this part, you must know how a Decorator design pattern works and how to make a new one.
On Android, communicating with a Bluetooth device requires an instance of BluetoothGatt
and an instance of BluetoothGattCallback
. RxBluetoothKotlin wraps both of theses types into RxBluetoothGatt
and RxBluetoothGatt.Callback
types to add some reactive touch to the system objects. Both RxBluetoothGatt
and RxBluetoothGatt.Callback
are interfaces, calling connectRxGatt
will return a default implementation for both of them but you are free to wrap the returned implementation by your own implementation to add you own behavior, you only have to follow the Decorator rules.
Decorate RxBluetoothGatt
The following diagram will show you which classes are used to create the decorator pattern:
[comment]: <> (Used syntax
"""
[BluetoothGatt{bg:cornsilk}]<1-<>[<>{bg:lavender}]
[<>]^-.-[RxBluetoothGattImpl{bg:lavender}]
[<>]^-.-[SimpleRxBluetoothGatt{bg:lavender}]
[<>]<1-<>[SimpleRxBluetoothGatt]
[SimpleRxBluetoothGatt]^-[An other Decorator{bg:lightblue}]
[SimpleRxBluetoothGatt]^-[Your Decorator{bg:lightblue}]lue}]
"""
On this website https://yuml.me/diagram/scruffy/class/draw
)
As you can see, to create a decorator, you only have to subclass SimpleRxBluetoothGatt
. If you want to decorate RxBluetoothGatt.Callback
just subclass SimpleRxBluetoothGattCallback
like you do with SimpleRxBluetoothGatt
from the previous example.
When your decorators are written you can send them to RxBluetoothKotlin by setting the rxGattBuilder
and rxCallbackBuilder
parameters when calling connectRxGatt
. Defaults implementation of RxBluetoothKotlin uses RxBluetoothGattImpl
and RxBluetoothGattCallbackImpl
, by using you own decorator you can change the way RxBluetoothKotlin is communicating with the Android SDK in order to match your own requirements.
Links
Report an issue by using github
Follow me on Twitter @VincentMsls
Discover our Equisense sensors
//TODO
-
Getting started
-
Licence