I have job scheduler which searches BLE devices and connects in background. Android 10 introduced new ACCESS_BACKGROUND_LOCATION permission. Does ACCESS_BACKGROUND_LOCATION permission require to connection BLE device in background?
https://developer.android.com/guide/topics/connectivity/bluetooth#Permissions only mentions the app needs ACCESS_FINE_LOCATION, so I suspect you don't need ACCESS_BACKGROUND_LOCATION. But I see it likely this will be changed in the near future.
A quick look at https://android.googlesource.com/platform/packages/apps/Bluetooth/+/refs/tags/android-10.0.0_r32/src/com/android/bluetooth/gatt/GattService.java#1949 shows that only the fine permission seems to be needed, but I can have missed something.
I suggest you to simply try with only ACCESS_FINE_LOCATION to see what happens in the background.
I Think this article would help as it talks about location permission in android 11 and use of BLE.
Location.
also i would recommend you use Foreground services to give your user more insight on what your app is doing and allow them to determine if they need to give you app the permission once, or always.
Running a service in the foreground
Android documentation says:
If your app supports a service and can run on Android 10 (API level 29) or Android 11, you must also declare the ACCESS_BACKGROUND_LOCATION permission to discover Bluetooth devices. For more information on this requirement, see Access location in the background.
More information here: Android bluetooth permissions
So answer is: If you scan for devices or connect to them from service (even foreground service) you need to request for ACCESS_BACKGROUND_LOCATION permission.
Related
Description:
I am scanning the nearby BLE devices in my android application and allowing users for these permissions ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION which requires enabling location in the Android device.
What I am looking for:
I need to remove the location permission from the app to scan nearby devices.
On Android 12 and higher, you should be able to use BLUETOOTH_SCAN as the permission.
On older devices, you have no choice but to request ACCESS_FINE_LOCATION. You do not need ACCESS_COARSE_LOCATION.
I believe it is not possible to do what you are trying to achieve. for more information check the android developer documentation.
https://developer.android.com/guide/topics/connectivity/bluetooth/ble-overview
I have an app, which implements Bluetooth LE Scanning (by extending BroadcastReceiver) to identify when the device is nearby a beacon.
I am experiencing some unexpected behaviour when testing on Android 10 & 11 with targetSDK = 30. I understand that in API 29 (Android 10) the background location permission was introduced and that this permission in required for Bluetooth LE Scanning.
However, when I test my app on Android 10 the scanning functionality works correctly without the ACCESS_BACKGROUND_LOCATION permission in my manifest. It identifies a nearby beacon if the app is in the foreground, the background or closed.
When I test my app on Android 11 the scanning functionality only works if the device is with range of a beacon and the app is brought from the background into the foreground. It doesn't work if the app is in the background or running in the foreground, only in this transition state.
If I add the ACCESS_BACKGROUND_LOCATION permission in my manifest and request this permission at runtime (in the incremental fashion Google enforce) then as long as the user has given at least foreground permissions then the scanning functionality works as expected.
I'm a bit confused by this behaviour specifically:
If the ACCESS_BACKGROUND_LOCATION permission was added in API 29 then why am I not seeing the behaviour I'm seeing on Android 11 on my Android 10 device?
Why do I need the ACCESS_BACKGROUND_LOCATION permission when even if a user only gives me foreground permissions (i.e. doesn't select 'Allow All The Time') then it still works and why is this needed for it to work in the foreground also?
This is more of a general question, but to what extent can we use the Nearby Connections API in services?
I noticed that discovery and pairing is still working while the app is out of focus, so is it possible to extract the whole connections client into a foreground- or even a background service which is running while the app itself doesn't have to?
There are no restrictions on using Nearby Connections from a service. However, Android has always somewhat aggressively killed background services (and is more aggressive since Android Oreo). There's also no way to limit the power, so advertising, scanning, and maintaining a connection for a long period of time will adversely effect battery life. There's a plan to expose a low power flag, but there's no ETA.
Disclaimer: I work on Nearby Connections
On devices running Android Q or higher, an ACCESS_FINE_LOCATION permission has to be requested to use Nearby Connections. When an app runs a background service, like a JobService, using Nearby Connections on a device running Android Q or higher, the app will not be able to discover nor to advertise, unless the ACCESS_BACKGROUND_LOCATION permission has been granted to the app by Google. To get it granted by Google, you have to explain in detail why your app needs it, and there is no guarantee that you will get it. This said, on Android versions lower that Q, an app can successfully discover and advertise in a background service, as long as it has requested all the nedded permissions (BLUETOOTH, BLUETOOTH_ADMIN, ACCESS_WIFI_STATE, CHANGE_WIFI_STATE and ACCESS_COARSE_LOCATION).
We are working on an app that needs to scan for iBeacons in background. We did a lot of optimizations and now it works well on Kitkat and Lollipop devices without consuming much battery.
On Marshmallow we require fine location permission to scan for iBeacons (coarse location has delays). This drains a lot of battery even if we have the same battery saving logic in place.
Is there a way that we can release fine location permission when the device is still (no movement) and acquire it when we see a movement? Since the user would have provided the runtime permission at app launch, re-acquiring that permission shouldn't bring the permission dialog again.
If there is way to achieve this, it would help us save the battery drain problem.
A few points:
Scanning for BLE devices requires either android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION It doesn't matter which one an app obtains.
In my tests, there is no difference in BLE device scanning performance between either of the above permissions. For this reason, the Android Beacon Library documentation suggests requesting android.permission.ACCESS_COARSE_LOCATION, and declares this permission in its manifest.
Declaring, requesting or obtaining a permission has no affect on battery drain. It is actually doing location-specific operations (BLE scanning, requesting GPS location updates, etc.) that affects battery usage.
The description of the problem says the app uses more battery when android.permission.ACCESS_FINE_LOCATION is obtained vs. android.permission.ACCESS_COARSE_LOCATION. Because of the points above, I do not believe the difference is explained beacon scanning. A possible alternative explanation is that the app is requesting location updates from the operating system (since I can't see the code, I don't know if this is true -- it's just a theory). If ACCESS_FINE_LOCATION is obtained, then that will unlock the GPS_PROVIDER, potentially powering up the GPS and causing the additional battery drain described.
See: http://developer.android.com/guide/topics/location/strategies.html
Note: If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then you need to request only the ACCESS_FINE_LOCATION permission, because it includes permission for both providers. (Permission for ACCESS_COARSE_LOCATION includes permission only for NETWORK_PROVIDER.)
I am asking a follow up question to my previously asked question -> http://stackoverflow.com/questions/33607410/background-monitoring-of-eddystone-beacon-using-altbeacon-library-on-android-pla/33613116?noredirect=1#comment55139316_33613116.
Where i was able to successfully detect beacons both in the foreground and background until I found out that the same code was unable to detect the beacon when i try to run it on nexus 5 device running android 6.0.
Can anyone provide a explanation to why this is happening? Thanks.
Android 6.0 imposes two new requirements in order for apps to detect BLE Beacons:
Location Services must be turned on in settings. Settings -> Location -> On. The specific mode may be either "High Accuracy" or "Device Saving". This is a new requirement that appears to be being rolled out to all firmware builds from Google. Without this on, BLE scans discover no devices.
The app must be given runtime permissions by the user to ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION. You must code your app to present one of these permission requests to the user. If not granted, the app will not be able to detect BLE Beacons.
A detailed explanation of this process is in my blog post here: Is Your Beacon App Ready For Android 6.0?
With Android 6.0, you now need to request location permissions at runtime in order to be able to discover beacons.
From our initial tests: if your app targets SDK < 23 (i.e., pre-Android 6.0), you will only need these permissions to detect beacons in the background. If your app targets SDK >= 23 (i.e., Android 6.0 or later), you will need these permissions to detect beacons both in the background and in the foreground. You also need to have Location enabled on your Android 6.0 device for both cases.
Google has a detailed guide on how to implement checking for and requesting runtime permissions:
http://developer.android.com/training/permissions/requesting.html
Specifically, you need either ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION. They both actually display the same message ("Allow APP_NAME to access your location?") to the user.