discoverServices method
Discover services, characteristics, and descriptors of the remote device
- Note:
discoverServicesmust be re-called after every connection! subscribeToServicesChangedAndroid & Linux Only: If true, after discovering services we will subscribe to the Services Changed Characteristic (0x2A05) used for thedevice.onServicesResetstream. Note: this behavior happens automatically on iOS and cannot be disabled
Implementation
Future<List<BluetoothService>> discoverServices(
{bool subscribeToServicesChanged = true, int timeout = 15}) async {
// check connected
if (isDisconnected) {
throw FlutterBluePlusException(ErrorPlatform.fbp, "discoverServices",
FbpErrorCode.deviceIsDisconnected.index, "device is not connected");
}
// Only allow a single ble operation to be underway at a time
_Mutex mtx = _MutexFactory.getMutexForKey("global");
await mtx.take();
List<BluetoothService> result = [];
try {
var responseStream = FlutterBluePlusPlatform.instance.onDiscoveredServices
.where((p) => p.remoteId == remoteId);
// Start listening now, before invokeMethod, to ensure we don't miss the response
Future<BmDiscoverServicesResult> futureResponse = responseStream.first;
// invoke
await FlutterBluePlus._invokePlatform(() => FlutterBluePlusPlatform.instance
.discoverServices(BmDiscoverServicesRequest(remoteId: remoteId)));
// wait for response
BmDiscoverServicesResult response = await futureResponse
.fbpEnsureAdapterIsOn("discoverServices")
.fbpEnsureDeviceIsConnected(this, "discoverServices")
.fbpTimeout(timeout, "discoverServices");
// failed?
if (!response.success) {
throw FlutterBluePlusException(_nativeError, "discoverServices",
response.errorCode, response.errorString);
}
// return primary services
result = response.services
.map((p) => BluetoothService.fromProto(p))
.where((p) => p.isPrimary)
.toList();
result = result;
} finally {
mtx.give();
}
// in order to match iOS behavior on all platforms (except web),
// we always listen to the Services Changed characteristic if it exists.
if (subscribeToServicesChanged) {
if (!kIsWeb && !Platform.isIOS && !Platform.isMacOS) {
BluetoothCharacteristic? c = _servicesChangedCharacteristic;
if (c != null &&
(c.properties.notify || c.properties.indicate) &&
c.isNotifying == false) {
await c.setNotifyValue(true);
}
}
}
return result;
}