setNotifyValue method
Sets notifications or indications for the characteristic.
- If a characteristic supports both notifications and indications, we use notifications. This is a limitation of CoreBluetooth on iOS.
forceIndications
Android Only. force indications to be used instead of notifications.
Implementation
Future<bool> setNotifyValue(bool notify, {int timeout = 15, bool forceIndications = false}) async {
// check connected
if (device.isDisconnected) {
throw FlutterBluePlusException(
ErrorPlatform.fbp, "setNotifyValue", FbpErrorCode.deviceIsDisconnected.index, "device is not connected");
}
// check
if (!kIsWeb && !Platform.isAndroid) {
assert(forceIndications == false, "Only Android supports forcing indications");
}
// Only allow a single ble operation to be underway at a time
_Mutex mtx = _MutexFactory.getMutexForKey("global");
await mtx.take();
try {
var request = BmSetNotifyValueRequest(
remoteId: remoteId,
serviceUuid: serviceUuid,
characteristicUuid: characteristicUuid,
forceIndications: forceIndications,
enable: notify,
primaryServiceUuid: primaryServiceUuid,
);
// Notifications & Indications are configured by writing to the
// Client Characteristic Configuration Descriptor (CCCD)
Stream<BmDescriptorData> responseStream = FlutterBluePlusPlatform.instance.onDescriptorWritten
.where((p) => p.remoteId == request.remoteId)
.where((p) => p.serviceUuid == request.serviceUuid)
.where((p) => p.characteristicUuid == request.characteristicUuid)
.where((p) => p.descriptorUuid == cccdUuid)
.where((p) => p.primaryServiceUuid == request.primaryServiceUuid);
// Start listening now, before invokeMethod, to ensure we don't miss the response
Future<BmDescriptorData> futureResponse = responseStream.first;
// invoke
bool hasCCCD = await FlutterBluePlus._invokeMethod(() => FlutterBluePlusPlatform.instance.setNotifyValue(request));
// wait for CCCD descriptor to be written?
if (hasCCCD) {
BmDescriptorData response = await futureResponse
.fbpEnsureAdapterIsOn("setNotifyValue")
.fbpEnsureDeviceIsConnected(device, "setNotifyValue")
.fbpTimeout(timeout, "setNotifyValue");
// failed?
if (!response.success) {
throw FlutterBluePlusException(_nativeError, "setNotifyValue", response.errorCode, response.errorString);
}
}
} finally {
mtx.give();
}
return true;
}