subscribeToCharacteristic method
Future<Stream<BleCharacteristicValue> >
subscribeToCharacteristic(
- BleCharacteristic characteristic
override
Subscribes to a Bluetooth characteristic to listen for updates.
A caller to this function will receive a Stream of BleCharacteristicValue objects. A caller should listen to this stream and establish a callback function invoked each time a new value is emitted to the stream. Once subscribed, any updates to the characteristic value will be sent as a stream of BleCharacteristicValue objects.
The broadcast stream contains only updates matching both the address and UUID of characteristic, ignoring case.
Subscribing to another characteristic or starting another BLE operation does not replace its notification
receiver. Cancelling a listener does not disable native notifications; use unsubscribeFromCharacteristic to
disable them.
Implementation
@override
Future<Stream<BleCharacteristicValue>> subscribeToCharacteristic(
BleCharacteristic characteristic,
) async {
final String address = characteristic.address.toUpperCase();
final String uuid = characteristic.uuid.toUpperCase();
final Stream<BleCharacteristicValue> stream =
BleMethodChannelRouter.forChannel(channel)
.characteristicChanges
.where((MethodCall call) {
final Object? arguments = call.arguments;
if (arguments is! Map<Object?, Object?>) {
throw const FormatException(
'Characteristic notification must contain a map.',
);
}
final Object? eventAddress = arguments['deviceAddress'];
final Object? eventUuid = arguments['characteristicUuid'];
if (eventAddress is! String || eventUuid is! String) {
throw const FormatException(
'Characteristic notification must identify its device and UUID.',
);
}
return eventAddress.toUpperCase() == address &&
eventUuid.toUpperCase() == uuid;
}).map(
(MethodCall call) => BleCharacteristicValue.fromMap(
call.arguments as Map<Object?, Object?>,
),
);
// Trigger the subscription to the characteristic on the platform side.
try {
await channel.invokeMethod('subscribeToCharacteristic', {
'address': characteristic.address,
'characteristicUuid': characteristic.uuid,
});
} on PlatformException catch (e) {
// Handle different error types accordingly.
if (e.message?.contains('permissions') ?? false) {
throw BluetoothPermissionException('Permission error: ${e.message}');
} else {
throw BluetoothSubscriptionException(
'Failed to subscribe to BLE characteristic: ${e.message}',
);
}
}
return stream;
}