Для настройки всех возможных уведомлений / показаний на любом заданном периферийном устройстве необходимо сначала подключиться к устройству, а затем обнаружить все службы и получить все подходящие характеристики.По этим характеристикам должны быть установлены уведомления / указания, а затем в паре с их источником (если это необходимо).
Пример кода:
device.establishConnection(false)
.flatMap(connection -> connection.discoverServices()
.map(RxBleDeviceServices::getBluetoothGattServices) // get them
.flatMapObservable(Observable::fromIterable) // map to individual services
.map(BluetoothGattService::getCharacteristics) // for each service take all characteristics
.flatMap(Observable::fromIterable) // map to individual characteristic)
.filter(characteristic -> (characteristic.getProperties() & (BluetoothGattCharacteristic.PROPERTY_NOTIFY | BluetoothGattCharacteristic.PROPERTY_INDICATE)) != 0) // consider only characteristics that have indicate or notify property
.flatMap(characteristic -> {
NotificationSetupper notificationSetupper;
if ((characteristic.getProperties() & BluetoothGattCharacteristic.PROPERTY_NOTIFY) != 0) {
notificationSetupper = setupNotifications(characteristic); // if supports notifications
} else {
notificationSetupper = setupIndications(characteristic); // else indications
}
return notificationSetupper.setupOn(connection);
})
)
.subscribe(
pair -> {
BluetoothGattCharacteristic characteristic = pair.first;
byte[] value = pair.second;
// do your thing with the emissions
},
throwable -> {
// log potential errors
}
);
Где помощники:
interface NotificationSetupper {
Observable<Pair<BluetoothGattCharacteristic, byte[]>> setupOn(RxBleConnection connection);
}
static NotificationSetupper setupNotifications(BluetoothGattCharacteristic characteristic) {
return connection -> connection.setupNotification(characteristic, getModeFor(characteristic))
.compose(pairNotificationsWith(characteristic));
}
static NotificationSetupper setupIndications(BluetoothGattCharacteristic characteristic) {
return connection -> connection.setupIndication(characteristic, getModeFor(characteristic))
.compose(pairNotificationsWith(characteristic));
}
static NotificationSetupMode getModeFor(BluetoothGattCharacteristic characteristic) { // a different mode is needed if a characteristic has no Client Characteristic Configuration Descriptor
UUID clientCharacteristicConfigurationDescriptorUuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
return characteristic.getDescriptor(clientCharacteristicConfigurationDescriptorUuid) != null ? NotificationSetupMode.DEFAULT : NotificationSetupMode.COMPAT;
}
static ObservableTransformer<Observable<byte[]>, Pair<BluetoothGattCharacteristic, byte[]>> pairNotificationsWith(BluetoothGattCharacteristic characteristic) { // to distinguish the source of notification we need to pair the value with the source
return upstream -> upstream.flatMap(it -> it).map(bytes -> Pair.create(characteristic, bytes));
}