Reputation: 9894
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);
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
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)
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?
Upvotes: 6
Views: 2868
Reputation: 1
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.
Upvotes: 0
Reputation: 3
The bug is in android 11. You need to ask them one by one.
Upvotes: 0
Reputation: 9894
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.
Upvotes: 2
Reputation: 13
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.
p.s If you find a better approach using BluetoothLeScanner object please let me know
.
Upvotes: 0
Reputation: 5682
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
ACCESS_FINE_LOCATION
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.
Upvotes: 0
Reputation: 13
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
Upvotes: 0