My app scans and connects to BLE devices from a foreground service. I want to upgrade SDK and target Android 12 (targetSdkVersion 32
) and support older versions of Android.
Android 12 introduced changes regarding bluetooth permissions.
Since Android 12: BLUETOOTH_ADVERTISE, BLUETOOTH_CONNECT, and BLUETOOTH_SCAN permissions are runtime permissions.
- If your app doesn't use Bluetooth scan results to derive physical location, you can make a strong assertion that your app never uses the Bluetooth permissions to derive physical location. To do so, complete the following steps:
Add the
android:usesPermissionFlags
attribute to yourBLUETOOTH_SCAN
permission declaration, and set this attribute's value toneverForLocation
.
- If location isn't otherwise needed for your app, remove the
ACCESS_FINE_LOCATION
permission from your app's manifest.
<manifest>
<!-- Include "neverForLocation" only if you can strongly assert that
your app never derives physical location from Bluetooth scan results. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
<!-- Not needed if you can strongly assert that your app never derives
physical location from Bluetooth scan results and doesn't need location
access for any other purpose. -->
<!--
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-->
...
</manifest>
I understand that the app should not request for the location permissions when the app runs on Android 12. My questions are:
ACCESS_FINE_LOCATION
, ACCESS_COARSE_LOCATION
and ACCESS_BACKGROUND_LOCATION
permissions presence in the Manifest ?ACCESS_BACKGROUND_LOCATION
. Should the app request for the background location access permission or not ? I am confused.Ad 1. Should my app request for the runtime location permissions when running on pre Android 12 ?
Yes. The app should request for the runtime location permissions when running on pre Android 12
Ad 2. What with ACCESS_FINE_LOCATION
, ACCESS_COARSE_LOCATION
and ACCESS_BACKGROUND_LOCATION
permissions presence in the Manifest ?
These entries should be present in the Manifest. Additionally mark them using android:maxSdkVersion
.
The manifest should resemble:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="package.com">
<!-- https://developer.android.com/guide/topics/connectivity/bluetooth/permissions -->
...
<!-- 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"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
android:maxSdkVersion="28"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
...
</manifest>
Ad 3. Should the app request for the ACCESS_BACKGROUND_LOCATION
permission when uses bluetooth from a foreground service ?
Yes. The app should request for it.
Depending on the Android version, the app should request for:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// `BLUETOOTH_SCAN` and `BLUETOOTH_CONNECT` on Android 12 and newer
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// `ACCESS_FINE_LOCATION` and `ACCESS_BACKGROUND_LOCATION` on Android 10..<12
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// `ACCESS_COARSE_LOCATION` and `ACCESS_FINE_LOCATION` on Android 7..<10
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// `ACCESS_COARSE_LOCATION` on Android 6
} else {
// None for previous versions
}