requestLEScan static method
Request the user to start scanning for Bluetooth LE devices in the area. Not every browser supports this method yet so check it using hasRequestLEScan. However even if the browser supports it, the Future may never complete on browsers. This has been the case for Chrome on linux and windows even with the correct flag enabled. Chrome on Android does seem to work. Add a Future.timeout to combat this.
The devices found through this are emitted using the 'advertisementreceived' event on addEventListener.
It will only emit devices that match the options
so it could happen
that there are no devices in range while the scan is running.
See BluetoothLEScanOptions for details on the options.
Once a scan is running (and there were no errors) it can be stopped by calling BluetoothLEScan.stop on the returned object from the Future. If this object doesn't get saved then there is no way to stop the scan, it should be able to start multiple scans with different scan options.
-
May throw UserCancelledDialogError if the user cancelled the dialog.
-
May throw NativeAPINotImplementedError if the browser/ user agent doesn't support this method. This may still be thrown even if hasRequestLEScan is checked first.
-
May throw StateError for any state error that the method may throw.
-
May throw PolicyError if Bluetooth has been disabled by an administrator via a policy.
-
May throw PermissionError if the user has disallowed the permission.
-
May throw MissingUserGestureError if the method is not called from a user gesture.
-
May throw BrowserError for every other browser error.
Implementation
static Future<BluetoothLEScan> requestLEScan(
final BluetoothLEScanOptions options) async {
if (!hasRequestLEScan()) {
throw NativeAPINotImplementedError("requestLEScan");
}
final promise = _nativeBluetooth.requestLEScan(options);
try {
final result = await _JSUtil.promiseToFuture(promise);
return BluetoothLEScan.fromJSObject(result);
} catch (e) {
final error = e.toString();
if (error.startsWith("InvalidStateError")) {
// The user probably canceled the permission dialog
if (error.toLowerCase().contains("user cancel")) {
// TODO: check if this is also the message on other browsers!
throw UserCancelledDialogError(error
.replaceFirst("InvalidStateError", "")
.replaceFirst(": ", ""));
}
throw StateError(
error.replaceFirst("InvalidStateError", "").replaceFirst(": ", ""));
} else if (error.startsWith("NotSupportedError")) {
throw NativeAPINotImplementedError("requestLEScan");
} else if (error.startsWith("NotAllowedError")) {
throw PermissionError("requestLEScan");
} else if (error.startsWith("SecurityError")) {
if (error.toLowerCase().contains("gesture")) {
throw MissingUserGestureError("requestLEScan");
}
throw PolicyError("requestLEScan");
}
if (e is Error) {
rethrow;
}
throw BrowserError(error);
}
}