scan method

Stream<BluetoothDevice> scan({
  1. Duration? timeout,
})

Starts a scan for Bluetooth Low Energy devices Timeout closes the stream after a specified Duration

Implementation

Stream<BluetoothDevice> scan({
  Duration? timeout,
}) async* {
  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(<BluetoothDevice>[]);

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

  yield* BluetoothManager.instance._methodStream
      .where((m) => m.method == "ScanResult")
      .map((m) => m.arguments)
      .takeUntil(Rx.merge(killStreams))
      .doOnDone(stopScan)
      .map((map) {
    final device = BluetoothDevice.fromJson(Map<String, dynamic>.from(map));
    final List<BluetoothDevice>? list = _scanResults.value;
    int newIndex = -1;
    list!.asMap().forEach((index, e) {
      if (e.address == device.address) {
        newIndex = index;
      }
    });

    if (newIndex != -1) {
      list[newIndex] = device;
    } else {
      list.add(device);
    }
    _scanResults.add(list);
    return device;
  });
}