0

My app was working well in 1.5.2, getting all BLE devices nearby.

Since the upgrade, I got no scan results. (This upgrade is mandatory as 1.5.2 is crashing when targeting Android 14 as required by Google by August 2024).

Looking at the logs, sounds like the turnOn() might be the problem.

(My lead platform is Android, so the question is related to the Android version and I didn't try the upgrade on iOS yet).

I listen to on/off state with:


    // handle bluetooth on & off
    // note: for iOS the initial state is typically BluetoothAdapterState.unknown
    // note: if you have permissions issues you will get stuck at BluetoothAdapterState.unauthorized
    // _bluetoothOnOffStreamSubscription?.cancel();
    _bluetoothOnOffStreamSubscription ??=
        FlutterBluePlus.adapterState.listen((BluetoothAdapterState state) {
      debugPrint("Bluetooth is: $state");
      if (state == BluetoothAdapterState.on) {
        // usually start scanning, connecting, etc
      } else {
        // show an error to the user, etc
      }
    });

    // == Add read values listeners
    _scanResultsStreamSubscription ??= FlutterBluePlus.scanResults.listen(
      (List<ScanResult> results) {
        debugPrint('Scanning devices nearby: found ${results.length}');

        if (!mounted) return;

        // == Add source devices to the list
        for (ScanResult result in results) {
          debugPrint(
              'Device [${result.device.name}] found nearby! rssi: ${result.rssi}');

          _addDeviceTolist(result);
        }

        if (results.length > 0) if (mounted)
          setState(() {
            // Force the refresh
            scanResultsCount += results.length;
          });
      },
      onError: (e) => print(e),
    );


    // turn on bluetooth ourself if we can
    // for iOS, the user controls bluetooth enable/disable
    if (Platform.isAndroid) {
      await FlutterBluePlus.turnOn();
    }

    FlutterBluePlus.startScan(
      // androidScanMode: AndroidScanMode.lowLatency,
      timeout: duration,
    ).catchError((e) {
      debugPrint("startScan exception: $e");
    });

As I see, first I get state on, but right after FBP logs turnOn returns false:

D/[FBP-Android](14379): [FBP] onMethodCall: turnOn
I/flutter (14379): Bluetooth is: BluetoothAdapterState.on
I/flutter (14379): [FBP] <turnOn> result: false

Any idea?

Full logs:

I/flutter (14379): Location permission is granted
I/flutter (14379): Read the information 1.3.16
I/flutter (14379): Geolocator status: inital value for _isLocationEnabled is true
I/flutter (14379): WiFi scanner: CanGetScannedResults.yes
I/flutter (14379): [FBP] <setLogLevel> result: true
I/flutter (14379): [FBP] <isSupported> args: null
D/[FBP-Android](14379): [FBP] onMethodCall: isSupported
I/flutter (14379): Location when in use permission is granted
I/flutter (14379): [FBP] <isSupported> result: true
I/flutter (14379): [FBP] <getAdapterState> args: null
D/[FBP-Android](14379): [FBP] onMethodCall: getAdapterState
I/flutter (14379): [FBP] <getAdapterState> result: {adapter_state: 4}
I/flutter (14379): [FBP] <turnOn> args: null
D/[FBP-Android](14379): [FBP] onMethodCall: turnOn
I/flutter (14379): Bluetooth is: BluetoothAdapterState.on
I/flutter (14379): [FBP] <turnOn> result: false
I/flutter (14379): Geolocator status: subscribing to stream
I/flutter (14379): Reading package information…
I/flutter (14379): [FBP] <setLogLevel> args: 5
I/flutter (14379): Read the information 1.3.16
D/[FBP-Android](14379): [FBP] onMethodCall: setLogLevel
I/flutter (14379): Start scanning ble devices nearby…
I/flutter (14379): SCANNING: false
I/flutter (14379): Location permission is granted
I/flutter (14379): Geolocator status: inital value for _isLocationEnabled is true
I/flutter (14379): [FBP] <setLogLevel> result: true
I/flutter (14379): [FBP] <isSupported> args: null
D/[FBP-Android](14379): [FBP] onMethodCall: isSupported
I/flutter (14379): Location when in use permission is granted
I/flutter (14379): [FBP] <isSupported> result: true
I/flutter (14379): [FBP] <turnOn> args: null
D/[FBP-Android](14379): [FBP] onMethodCall: turnOn
I/flutter (14379): Dispose (Geolocator status: )
I/flutter (14379): Stop scanning ble devices nearby
W/WindowOnBackDispatcher(14379): sendCancelIfRunning: isInProgress=falsecallback=io.flutter.embedding.android.FlutterActivity$1@c3801c4
I/flutter (14379): [FBP] stopScan: already stopped
I/flutter (14379): Done stopScan()
I/flutter (14379): [FBP] <turnOn> result: false
I/flutter (14379): [FBP] <turnOn> args: null
D/[FBP-Android](14379): [FBP] onMethodCall: turnOn
I/flutter (14379): isScanning: true
I/flutter (14379): [FBP] <turnOn> result: false
I/flutter (14379): [FBP] <startScan> args: {with_services: [], with_remote_ids: [], with_names: [], with_keywords: [], with_msd: [], with_service_data: [], continuous_updates: false, continuous_divisor: 1, android_scan_mode: 2, android_uses_fine_location: false}
D/[FBP-Android](14379): [FBP] onMethodCall: startScan
D/WifiScanPlugin(14379): onRequestPermissionsResult: arguments (1454, [Ljava.lang.String;@b45ef43, [I@c7f79c0)
D/WifiScanPlugin(14379): requestPermissionCookie: {}
I/flutter (14379): isScanning: false
I/flutter (14379): Scanning devices nearby: found 0
I/flutter (14379): [FBP] stopScan: already stopped

[UPDATE]

I did a couple of things:

  1. First I downgraded targetSdkVersion to 33 as before and still no scan result;
  2. Still in targetSdkVersion 33, I replaced my app widget in the main by the demo app provided by the flutter_blue_plus team and get the same 0 scan results.

The logs are below.

Connecting to VM Service at ws://127.0.0.1:49838/IV8Mmm-MLFw=/ws
D/[FBP-Android](11231): [FBP] onMethodCall: flutterRestart
D/[FBP-Android](11231): [FBP] initializing BluetoothAdapter
I/flutter (11231): [FBP] <setLogLevel> args: 5
D/[FBP-Android](11231): [FBP] disconnectAllDevices(flutterRestart)
D/[FBP-Android](11231): [FBP] connectedPeripherals: 0
D/[FBP-Android](11231): [FBP] onMethodCall: setLogLevel
I/flutter (11231): [FBP] <setLogLevel> result: true
I/flutter (11231): [FBP] <getAdapterState> args: null
D/[FBP-Android](11231): [FBP] onMethodCall: getAdapterState
I/flutter (11231): [FBP] <getAdapterState> result: {adapter_state: 4}
I/flutter (11231): [FBP] <getSystemDevices> args: null
D/[FBP-Android](11231): [FBP] onMethodCall: getSystemDevices
I/flutter (11231): [FBP] <getSystemDevices> result: {devices: []}
I/flutter (11231): [FBP] <startScan> args: {with_services: [], with_remote_ids: [], with_names: [], with_keywords: [], with_msd: [], with_service_data: [], continuous_updates: false, continuous_divisor: 1, android_scan_mode: 2, android_uses_fine_location: false}
D/[FBP-Android](11231): [FBP] onMethodCall: startScan
D/BluetoothAdapter(11231): isLeEnabled(): ON
D/BluetoothLeScanner(11231): onScannerRegistered() - status=0 scannerId=3 mScannerId=0
I/flutter (11231): [FBP] <startScan> result: true
I/flutter (11231): [FBP] <stopScan> args: null
D/[FBP-Android](11231): [FBP] onMethodCall: stopScan
D/BluetoothAdapter(11231): isLeEnabled(): ON
I/flutter (11231): [FBP] <stopScan> result: true

My manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.olenpepsmobile">

    <!-- Enables BLE communications -->
         <!-- Request legacy Bluetooth permissions on older devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH"
    android:maxSdkVersion="30" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
        android:maxSdkVersion="30" />

    <!-- Needed only if your app looks for Bluetooth devices.
    If your app doesn't use Bluetooth scan results to derive physical
    location information, you can
    <a href="#assert-never-for-location">strongly assert that your app
    doesn't derive physical location</a>. -->
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />

    <!-- Needed only if your app makes the device discoverable to Bluetooth
    devices. -->
    <!-- <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> -->

    <!-- Needed only if your app communicates with already-paired Bluetooth
    devices. -->
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />

    <!-- Needed only if your app uses Bluetooth scan results to derive physical location. -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!-- <uses-permission android:name="android.permission.BLUETOOTH" />  
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />   -->

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>  
    <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 

    <application
        android:label="Olenergies Batteries"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"
        android:enableOnBackInvokedCallback="true"
        >
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

My build.gradle:

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services'


def keystoreProperties = new Properties()
   def keystorePropertiesFile = rootProject.file('key.properties')
   if (keystorePropertiesFile.exists()) {
       keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
   }

android {
    compileSdkVersion 33//34 //flutter.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        applicationId "com.olenergies.olenpepsmobile"
        minSdkVersion 21
        targetSdkVersion 34
        // Fix to 34 to comply with Google injonction by July 4th 2024
        // Fix to 33 to comply with Google injonction by August 31st 2023
        //31 // Fix to Android 12 to solve permission issue on Android 13 https://stackoverflow.com/questions/76092585/filepicker-missing-permission-on-android-13-pixel-7/76092681#76092681
        //flutter.targetSdkVersion
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword keystoreProperties['storePassword']
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
            // Sdl on Thursday May 12th 2022: remove shriking to let flutter blue plus scan working
            //signingConfig signingConfigs.debug
            shrinkResources false
            minifyEnabled false
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:multidex:1.0.3'
}
2
  • 1
    Android 12 and higher needs different Permissions that 11 and below: developer.android.com/develop/connectivity/bluetooth/… Could that be the problem? I'm not sure from which target version you updated to 14, but that sounds related Commented Jul 8 at 6:58
  • 1
    Thanks but alas, all the permissions are ok and conform to the link you provided. I even downgraded the version of my app to target Android 13 as before and no result at all. Still investigating. Commented Jul 8 at 8:14

1 Answer 1

1

I finally managed to make it works by aligning version for both targetSdkVersion and compileSdkVersionin the build.gradle.

Not the answer you're looking for? Browse other questions tagged or ask your own question.