dotintent / FlutterBleLib

Bluetooth Low Energy library for Flutter with support for simulating peripherals
Apache License 2.0
537 stars 197 forks source link

stopPeripheralScan does not work how it should work #553

Open albo1337 opened 3 years ago

albo1337 commented 3 years ago

Hey,

if I stopPeripheralScan and start it again I receive immediatly an error (16ms). Tested on iOS. So I have no idea what I am doing wrong but here is my code snippet:

  Future<bool> connectToButton() async {
    _bleManager = BleManager();
    await _bleManager
        .createClient(restoreStateIdentifier: bleConstants.restoreId)
        .catchError((e) {
      print("_bleManager got error: $e");
      return false;
    });

    await _checkPermissions().catchError((e) {
      print("_checkPermissions got error: $e");
      return false;
    });

    await _waitForBluetoothPoweredOn().catchError((e) {
      print("_waitForBluetoothPoweredOn got error: $e");
      throw BluetoothIsNotOnError();
    });

    await _startPeripheralScan().catchError((e) {
      print("_startPeripheralScan got error: $e");
      throw e;
    });

    _bleManager.destroyClient();
    return true;
  }

  Future _checkPermissions() async {
    try {
      if (Platform.isAndroid) {
        await Permission.location.request();
        var permissionStatus = await Permission.location.status;
        print(permissionStatus);
      }
      return Future.value();
    } catch (e) {
      return Future.error(PermissionNotGrantedError());
    }
  }

  Future _waitForBluetoothPoweredOn() async {
    try {
      Future<BluetoothState> future;
      future = _bleManager.observeBluetoothState().firstWhere((bluetoothState) {
        print(bluetoothState);
        if (bluetoothState == BluetoothState.POWERED_ON) {
          return true;
        } else {
          return false;
        }
      }).timeout(
        Duration(seconds: 3),
        onTimeout: () {
          return Future.error(BluetoothIsNotOnError());
        },
      );
      await future;
      return Future.value();
    } catch (e) {
      return Future.error(BluetoothIsNotOnError());
    }
  }

  Future _startPeripheralScan() async {
    try {
      ScanResult scanResult = await _bleManager
          .startPeripheralScan(uuids: [bleConstants.uuidButtonService])
          .first
          .timeout(
            Duration(seconds: 10),
            onTimeout: () {
              return Future.error(TimeOutError());
            },
          );
      print(scanResult);
      await _bleManager.stopPeripheralScan();
      _peripheral = scanResult.peripheral;
      return Future.value();
    } catch (e) {
      print(e);
      return Future.error(TimeOutError());
    }
  }

even when I replace the await _bleManager.stopPeripheralScan(); with _bleManager.stopPeripheralScan();it doesnt work.

What am I doing wrong? If I trigger the _startPeripheralScan() again after it failed it works again.

Best regards albo

mikolak commented 3 years ago

Why do you destroy the client after each iteration? It should be kept alive as long as you need it.

Can you set log level to verbose (bleManager.setLogLevel(LogLevel.verbose)) and run your app from XCode?