scan method

Stream<ScanResult> scan({
  1. ScanMode scanMode = ScanMode.lowLatency,
  2. List<Guid> withServices = const [],
  3. List<Guid> withDevices = const [],
  4. Duration? timeout,
  5. bool allowDuplicates = false,
})

Starts a scan for Bluetooth Low Energy devices and returns a stream of the ScanResult results as they are received.

timeout calls stopStream after a specified Duration. You can also get a list of ongoing results in the scanResults stream. If scanning is already in progress, this will throw an Exception.

Implementation

Stream<ScanResult> scan({
  ScanMode scanMode = ScanMode.lowLatency,
  List<Guid> withServices = const [],
  List<Guid> withDevices = const [],
  Duration? timeout,
  bool allowDuplicates = false,
}) async* {
  var settings = protos.ScanSettings.create()
    ..androidScanMode = scanMode.value
    ..allowDuplicates = allowDuplicates
    ..serviceUuids.addAll(withServices.map((g) => g.toString()).toList());

  if (_isScanning.value == true) {
    throw Exception('Another scan is already in progress.');
  }

  // Emit to isScanning
  _isScanning.add(true);

  final killStreams = <Stream>[];
  killStreams.add(_stopScanPill);
  if (timeout != null) {
    killStreams.add(Rx.timer(null, timeout));
  }

  // Clear scan results list
  _scanResults.add(<ScanResult>[]);

  try {
    await _channel.invokeMethod('startScan', settings.writeToBuffer());
  } catch (e) {
    print('Error starting scan.');
    _stopScanPill.add(null);
    _isScanning.add(false);
    throw e;
  }

  yield* FlutterBlue.instance._methodStream
      .where((m) => m.method == "ScanResult")
      .map((m) => m.arguments)
      .takeUntil(Rx.merge(killStreams))
      .doOnDone(stopScan)
      .map((buffer) => new protos.ScanResult.fromBuffer(buffer))
      .map((p) {
    final result = new ScanResult.fromProto(p);
    final list = _scanResults.value;
    int index = list.indexOf(result);
    if (index != -1) {
      list[index] = result;
    } else {
      list.add(result);
    }
    _scanResults.add(list);
    return result;
  });
}