Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 15 additions & 131 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,20 @@ The library uses Java 1.8 features. If you're using Android Studio below 4.2, ma

### Recent changes

See [Releases](https://github.com/NordicSemiconductor/Android-BLE-Library/releases) for details.
Below is short summary:

<details>
<summary>Version 2.6</summary>

1. `getGattCallback()` method has been deprecated. Instead, simply move the inner methods to the
`BleManager` class. See [this PR](https://github.com/NordicSemiconductor/Android-nRF-Blinky/pull/78).
2. Support for *server only* implementation using `attachClientConnection(BluetoothDevice)`. Call it instead of
`connect(BluetoothDevice)` to use the device as server-only.
3. Data provider for read requests (server side) was added.
4. Cancellation support for flows and suspended methods added to `:ble-kts`.
</details>

<details>
<summary>Version 2.4</summary>

Expand Down Expand Up @@ -159,137 +173,7 @@ Check out [migration guide](MIGRATION.md).

## Usage

A `BleManager` instance is responsible for connecting and communicating with a single peripheral.
Having multiple instances of the manager is possible to connect with multiple devices simultaneously.
The `BleManager` must be extended with your implementation where you define the high level device's API.

```java
class MyBleManager extends BleManager {
private static final String TAG = "MyBleManager";

private BluetoothGattCharacteristic fluxCapacitorControlPoint;

public MyBleManager(@NonNull final Context context) {
super(context);
}

@Override
public int getMinLogPriority() {
// Use to return minimal desired logging priority.
return Log.VERBOSE;
}

@Override
public void log(int priority, @NonNull String message) {
// Log from here.
Log.println(priority, TAG, message);
}

@NonNull
@Override
protected BleManagerGattCallback getGattCallback() {
return new MyGattCallbackImpl();
}

private class MyGattCallbackImpl extends BleManagerGattCallback {
@Override
protected boolean isRequiredServiceSupported(@NonNull BluetoothGatt gatt) {
// Here get instances of your characteristics.
// Return false if a required service has not been discovered.
BluetoothGattService fluxCapacitorService = gatt.getService(FLUX_SERVICE_UUID);
if (fluxCapacitorService != null) {
fluxCapacitorControlPoint = fluxCapacitorService.getCharacteristic(FLUX_CHAR_UUID);
}
return fluxCapacitorControlPoint != null;
}

@Override
protected void initialize() {
// Initialize your device.
// This means e.g. enabling notifications, setting notification callbacks,
// sometimes writing something to some Control Point.
// Kotlin projects should not use suspend methods here, which require a scope.
requestMtu(517)
.enqueue();
}

@Override
protected void onServicesInvalidated() {
// This method is called when the services get invalidated, i.e. when the device
// disconnects.
// References to characteristics should be nullified here.
fluxCapacitorControlPoint = null;
}
}

// Here you may add some high level methods for your device:
public void enableFluxCapacitor() {
// Do the magic.
writeCharacteristic(fluxCapacitorControlPoint, Flux.enable(), BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE)
.enqueue()
}
}
```

The [BleManager](https://github.com/NordicSemiconductor/Android-BLE-Library/blob/master/ble/src/main/java/no/nordicsemi/android/ble/BleManager.java)
class exposes high level API for connecting and communicating with Bluetooth LE peripherals.

```java
connect(bluetoothDevice)
// Automatic retries are supported, in case of 133 error.
.retry(3 /* times, with */, 100 /* ms interval */)
// A connection timeout can be set. This is additional to the Android's connection timeout which is 30 seconds.
.timeout(15_000 /* ms */)
// The auto connect feature from connectGatt is available as well
.useAutoConnect(true)
// This API can be set on any Android version, but will only be used on devices running Android 8+ with
// support to the selected PHY.
.usePreferredPhy(PhyRequest.PHY_LE_1M_MASK | PhyRequest.PHY_LE_2M_MASK | PhyRequest.PHY_LE_CODED_MASK)
// A connection timeout can be also set. This is additional to the Android's connection timeout which is 30 seconds.
.timeout(15_000 /* ms */)
// Each request has number of callbacks called in different situations:
.before(device -> { /* called when the request is about to be executed */ })
.done(device -> { /* called when the device has connected, has required services and has been initialized */ })
.fail(device, status -> { /* called when the request has failed */ })
.then(device -> { /* called when the request was finished with either success, or a failure */ })
// Each request must be enqueued.
// Kotlin projects can use suspend() or suspendForResult() instead.
// Java projects can also use await() which is blocking.
.enqueue()
```

```java
writeCharacteristic(someCharacteristic, someData, BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE)
// Outgoing data can use automatic splitting.
.split(customSplitter, progressCallback /* optional */)
// .split() with no parameters uses the default MTU splitter.
// Kotlin projects can use .splitWithProgressAsFlow(customSplitter) to get the progress as Flow.
.before(device -> { /* called when the request is about to be executed */ })
.with(device, data -> { /* called when the request has been executed */ })
.done(device -> { /* called when the request has completed successfully */ })
.fail(device, status -> { /* called when the request has failed */ })
.invalid({ /* called when the request was invalid, i.e. the target device or given characteristic was null */ })
.then(device -> { /* called when the request was finished with either success, or a failure */ })
// Remember to enqueue each request.
.enqueue()
```

```java
readCharacteristic(someCharacteristic)
// Incoming data can use automatic merging.
.merge(customMerger, progressCallback /* optional */)
// Kotlin projects can use .mergeWithProgressAsFlow(customMerger) to get the progress as Flow.
// Incoming packets can also be filtered, so that not everything goes to the merger.
.filter(dataFilter)
// Complete, merged packets can also be filtered.
.filterPacket(packetFilter)
// [...]
.with(device, data -> { /* called when the data have been received */ })
// [...]
// Once again, remember to enqueue each request!
.enqueue()
```
All requests are automatically enqueued and executed sequentially.
See [Usage](USAGE.md) for more details.

## Examples

Expand Down
Loading