scanForFrame method
Future<void>
scanForFrame(
)
inherited
Implementation
Future<void> scanForFrame() async {
currentState = ApplicationState.scanning;
if (mounted) setState(() {});
// create a Future we can manually complete when Frame is found
// or timeout occurred, but either way we can await scanForFrame synchronously
final completer = Completer<void>();
await BrilliantBluetooth.requestPermission();
await _scanStream?.cancel();
_scanStream = BrilliantBluetooth.scan().timeout(const Duration(seconds: 5),
onTimeout: (sink) {
// Scan timeouts can occur without having found a Frame, but also
// after the Frame is found and being connected to, even though
// the first step after finding the Frame is to stop the scan.
// In those cases we don't want to change the application state back
// to disconnected
switch (currentState) {
case ApplicationState.scanning:
_log.fine('Scan timed out after 5 seconds');
currentState = ApplicationState.disconnected;
if (mounted) setState(() {});
break;
case ApplicationState.connecting:
// found a device and started connecting, just let it play out
break;
case ApplicationState.connected:
case ApplicationState.ready:
case ApplicationState.running:
case ApplicationState.starting:
case ApplicationState.canceling:
// already connected, nothing to do
break;
default:
_log.fine('Unexpected state on scan timeout: $currentState');
if (mounted) setState(() {});
// signal that scanForFrame can now finish
// if it hasn't already completed via the listen() path below
if (!completer.isCompleted) {
completer.complete();
}
}
}).listen((device) async {
_log.fine('Frame found, connecting');
currentState = ApplicationState.connecting;
if (mounted) setState(() {});
await connectToScannedFrame(device);
// signal that scanForFrame can now finish
completer.complete();
});
// wait until the listen(onData) or the onTimeout is completed
// so we can return synchronously
await completer.future;
}