Android BLE onScanResult is never called in the background on Android 11. Was working on Android 10

Viewed 606

I have an app which scans for BLE devices. It was working perfectly on Android 10, but since I updated my phone to Android 11, the onScanResult just never gets called if I put the application to the background, or if I lock the screen.

This is quite annoying. I haven't found any reasonable ideas what could cause this. I haven't found any differences in Android 11 whatsoever which would indicate this behavior change. Android 12 has new BT permissions if you target your app to api level 31, but I do target mine to api level 30, and I do run my app on Android 11.

I'm absolutely clueless. I've tried different scan modes, as well with adding scan filter but nothing has changed.

My scan settings:

ScanSettings ss = new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_POWER).build();
        List<ScanFilter> filterList = new ArrayList<>();
        filterList.add(new ScanFilter.Builder().setManufacturerData(Constants.HARDWARE_MANUFACTURER_ID, new byte[]{}).build());
        BluetoothUtil.getBluetoothLeScannerInstance().startScan(filterList, ss, leScanCallback);

So far I experience the following:

The onScanResult calls perfectly when the app is in the foreground and the device's screen is not locked. As soon as I push the app to the background or I lock the screen I no longer getting any callbacks for onScanResult

Here is an example log when the app is in the foreground, not locked screen:

15:47:15 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:47:17 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:21 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:21 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:22 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:22 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)
15:47:25 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:47:25 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:26 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:26 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:29 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:30 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:30 com.myapp.co I/SCANNED_: onScanResult ran!
15:47:32 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)

And an example log when the app is in background and or locked screen:

15:48:25 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:48:32 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)
15:48:35 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:48:42 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)
15:48:45 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:48:52 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)
15:48:55 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:49:02 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)
15:49:05 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:49:12 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)
15:49:15 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:49:22 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)
15:49:25 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:49:32 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)
15:49:35 com.myapp.co I/BL_START: ...Starting BL scan. (Start of current window)
15:49:42 com.myapp.co I/BL_STOP: ...Finishing BL scan. (End of current window)

As you can see the onScanResult are getting called as it should, when the app is in the foreground and the screen is not locked.

What may cause this, and how can I prevent such functionality?

5 Answers

Apparently, there is a bug in Android 11. If you ask both of the location permissions at the same time, it wouldn't pop the permission dialog. You have to ask them one by one.

make sure that your app defines all the mandatory permissions for BLE scanning. These permission requirements changed over time, so you have to be careful to have them all in your AndoroidManifest:


<!-- 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" />

<!-- Bluetooth permissions for BLE scanning -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

<!-- Location permissions for BLE scanning -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

Also make sure that

  • not only your app has granted permission for ACCESS_FINE_LOCATION
  • but also that you enable LocationServices at the OS level:

Location Services active

If you are using a Service to scan for devices, make sure that this Service is correctly defined as foreground service. This topic is to big to just pump out a code snippet. It's a bit of reading the documentation. But the docs are quite good here, so you should be fine.

I have been experiencing the same issue on Android 11. I will explain what I did so hopefully it can help you and someone having the same issue.

First, as I mentioned, make sure that you have all of the mandatory permissions for BLE scanning.

Second, go to your physical Android device and make sure that the application is not included in the "Optimize battery usage" applications if so, remove it from there and test the code again.

Lastly, all of those options did not help resolving my issue. Which was the same as yours. While I was trying to scan for a BLE devices with this scan settings:

 BluetoothAdapter.DefaultAdapter.BluetoothLeScanner.StartScan(scanFilters, scanSettingsBuilder.Build(),
                _customScanCallback);

my foreground service was working properly while on foreground, while in background, but not while the phone was locked. Reason, the callback was never called. What I did as a work around. It may not be the best possible solution but it is working. Use public static BluetoothAdapter Adapter => BluetoothAdapter.DefaultAdapter; and then call Adapter.StartDiscovery(); With other words try it without the BluetoothLEScanner object. Then in the OnReceive() method extract all of the needed information from the intent object that was passed as an argument. This is a snipped of my output while the Android 11 device is locked. enter image description here p.s If you find a better approach using BluetoothLeScanner object please let me know .

The bug is in android 11. You need to ask them one by one.

Related