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:
- First I downgraded targetSdkVersion to 33 as before and still no scan result;
- 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'
}