Flutter_blue: [Android] Crashes when Bluetooth Adapter is turned off

Created on 28 Jun 2018  路  6Comments  路  Source: pauldemarco/flutter_blue

FATAL EXCEPTION: main
Process: com.company.app, PID: 11091
java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1452, result=-1, data=Intent { act=android.content.pm.action.R
EQUEST_PERMISSIONS (has extras) }} to activity {com.company.app/com.company.app.MainActivity}: java.lang.IllegalArgumentException: Unsupported 
value: java.lang.IllegalStateException: getBluetoothLeScanner() is null. Is the Adapter on?
    at android.app.ActivityThread.deliverResults(ActivityThread.java:4339)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:4382)
    at android.app.ActivityThread.-wrap19(Unknown Source:0)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1654)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:251)
    at android.app.ActivityThread.main(ActivityThread.java:6572)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.IllegalArgumentException: Unsupported value: java.lang.IllegalStateException: getBluetoothLeScanner() is null. Is the Adapter on?
    at io.flutter.plugin.common.StandardMessageCodec.writeValue(StandardMessageCodec.java:293)
    at io.flutter.plugin.common.StandardMethodCodec.encodeErrorEnvelope(StandardMethodCodec.java:70)
    at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler$1.error(MethodChannel.java:199)
    at com.pauldemarco.flutterblue.FlutterBluePlugin.startScan(FlutterBluePlugin.java:602)
    at com.pauldemarco.flutterblue.FlutterBluePlugin.onRequestPermissionsResult(FlutterBluePlugin.java:495)
    at io.flutter.app.FlutterPluginRegistry.onRequestPermissionsResult(FlutterPluginRegistry.java:175)
    at io.flutter.app.FlutterActivityDelegate.onRequestPermissionsResult(FlutterActivityDelegate.java:132)
    at io.flutter.app.FlutterActivity.onRequestPermissionsResult(FlutterActivity.java:134)
    at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7388)
    at android.app.Activity.dispatchActivityResult(Activity.java:7239)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:4335)
    ... 9 more

Plugin should query for Adapter status first and turn it on (Android will prompt the user) before scanning.

Most helpful comment

This (or similar) code should be part of the plugin.

All 6 comments

I see this was intentional in #50, but I would expect it to work the other way. ;-)

@ened - did you figure out a way around this? Is there a way to turn the adapter on in case it is off?

@suparnavg yes, with the help of the android_intent plugin:

First, check for the bluetooth state and handle cases for devices without bluetooth functions (emulator etc).

final btState =
    await flutterBlue.state.catchError((e) => BluetoothState.unavailable);
if (btState == BluetoothState.unavailable) {
  // notify the error
  return;
}

Finally, prompt the user to activate Bluetooth:

if (btState != BluetoothState.on) {
  if (Platform.isAndroid) {
    // This will trigger a dialog ("Application wants to turn on Bluetooth, do you want to allow it?")
    const intent = AndroidIntent(
      action: 'android.bluetooth.adapter.action.REQUEST_ENABLE',
    );
    await intent.launch();

    // We wait 5 seconds - fixed.
    // This is a tricky bit, because if the user waits on the aforementioned dialog for more than 5 seconds, we still have a disabled bluetooth adapter below.
    // Also can not wait forever, so prepare your UI to switch back to a "un-connected" status.
    await Future.delayed(Duration(seconds: 5));
  }

  if (await flutterBlue.state != BluetoothState.on) {
    // Switch UI back to "not connected".
    return;
  }
}

This (or similar) code should be part of the plugin.

@ened thanks for the tip!

@ened, thanks for the workaround. When I implemented the same, it gave me these:

  • The method 'catchError' isn't defined for the type 'Stream'. _error_, so I changed it to handleError,
  • Equality operator '==' invocation with references of unrelated types _warning_ on:

    • 'await' applied to 'Stream<BluetoothState>', which is not a 'Future'.,

    • btState == BluetoothState.unavailable,

    • btState != BluetoothState.on and

    • await flutterBlue.state != BluetoothState.on

@pauldemarco if it's BluetoothState.unavaiable then wouldn't it be neat to have BluetoothState.available instead of BluetoothState.on, cause on happens to be a reserved word?

I'm new to flutter and would appreciate all help.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

janekm picture janekm  路  3Comments

ekuleshov picture ekuleshov  路  3Comments

FWeissenb picture FWeissenb  路  5Comments

brianegan picture brianegan  路  5Comments

coduy96 picture coduy96  路  5Comments