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

6

6

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?

Superintend answered 2/12, 2021 at 14:57 Comment(0)
S
2

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.

Superintend answered 6/12, 2021 at 20:16 Comment(0)
H
0

It is hard to be said with the information provided but one reason could be that Android 11 requires "Background location Access" in the Manifest to work in a background mode.

You may take a look in here for more details: https://developer.android.com/about/versions/11/privacy/foreground-services

Herald answered 3/12, 2021 at 17:32 Comment(1)
What do you mean it is hard to say with the info I provided, what is missing?Superintend
I
0

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.

Impacted answered 5/12, 2021 at 21:25 Comment(0)
H
0

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 .

Herald answered 6/12, 2021 at 17:9 Comment(0)
B
0

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

Binkley answered 11/12, 2021 at 16:45 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Giguere
B
0

Access to the device location in the background requires permission.

To support the additional control that users have over an app's access to location information, Android 10 introduces the ACCESS_BACKGROUND_LOCATION permission.

Unlike the ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions, the ACCESS_BACKGROUND_LOCATION permission only affects an app's access to location when it runs in the background. An app is considered to be accessing location in the background unless one of the following conditions is satisfied:

1.An activity belonging to the app is visible.

2.The app is running a foreground service that has declared a foreground service type of location.

To declare the foreground service type for a service in your app, set your app's targetSdkVersion or compileSdkVersion to 29 or higher. Learn more about how foreground services can continue user-initiated actions that require access to location.

If your app creates and monitors geofences and targets Android 10 (API level 29) or higher, you must declare the ACCESS_BACKGROUND_LOCATION permission.

You can find more here.

And you need to be aware that when you request ACCESS_BACKGROUND_LOCATION permission, it leads you directly to the setting page. So this permission can not be requested together with other Bluetooth Permissions. Doing so will cause abnormal behaviour that no permission dialogue box will be popped up.

Bluefarb answered 10/11, 2022 at 9:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.