Credits for the answer to @Stephen Ruda
I have run into the exact same problem. I agree that this is an issue for any developer who needs background location permission. I would like to add additional notes for other readers:
(1) On API 30+ you will first need basic location permissions before asking for background location permission - otherwise, it won't go to the permission screen at all.
(2) When you ask for background location permission and it sends them to the permission request screen, it will only 'lock' the user out if they ONLY hit the back button. If they tap any of the options and then back the request will work again.
Answer from Victor Laerte on Stack OverflowAndroid 11 users can’t grant background location permission? - Stack Overflow
kotlin - How to access background location permission on runtime in android 13? - Stack Overflow
When to use access background location permission? Android Java - Stack Overflow
ACCESS_BACKGROUND_LOCATION permission (declaration form) confusion
I've looked into this recently, and what I noted down is
-
it's an install-time permission; you do not request it at runtime with
requestPermissions -
"On Android 11 (API level 30) and higher, if your app starts a foreground service while running in the background," the service cannot access location, unless the user has granted the ACCESS_BACKGROUND_LOCATION permission to your app.
-
So, let's say a user of your app presses a button, and it starts a foreground service that requires location access. For that, you wouldn't need this permission, because you start the service while the app is not in the background.
-
An app is considered to be running in the background as long as each of the following conditions are satisfied:
-
None of the app's activities are currently visible to the user.
-
The app isn't running any foreground services that started while an activity from the app was visible to the user.
-
-
As I understand it, as long as you start a foreground service while the app is in the foreground, you don't need this permission, because the user will already have permitted foreground access to their location, f.e. with
ACCESS_FINE_LOCATION
This is my take on it, but I might be wrong.
Oh and if you end up needing this permission after all, you also have to add android:foregroundServiceType="location" to your service in the manifest.
Videos
Credits for the answer to @Stephen Ruda
I have run into the exact same problem. I agree that this is an issue for any developer who needs background location permission. I would like to add additional notes for other readers:
(1) On API 30+ you will first need basic location permissions before asking for background location permission - otherwise, it won't go to the permission screen at all.
(2) When you ask for background location permission and it sends them to the permission request screen, it will only 'lock' the user out if they ONLY hit the back button. If they tap any of the options and then back the request will work again.
you cannot request foreground and background permission same time and cannot request background location permission without foreground permission granted. Therefore first you have to request foreground permission and then 'onRequestPermissionsResult' you can request background permission
First in onCreate
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
new String[]{
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
},
1
);
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},
1
);
}
}
}
}
With the upcoming Location permission declaration policy requirement, can someone please explain how android.permission.ACCESS_BACKGROUND_LOCATION supposed to work, when it's required, especially for foreground services, how to request it, when it's granted, and when a policy declaration form submission is needed?
The official documentation is vague and contradicting...
-
Supposedly a "foreground service" (app) shouldn't use the permission at all, but the GMS Geofencing API seem to require it!?
-
Getting location updates doesn't require the permission?
-
Is the permission required for every other feature needing
ACCESS_COURSE_LOCATIONorACCESS_FINE_LOCATION, e.g. Bluetooth, Wi-Fi,CellInfo? -
It's said we should perform incremental location permission requests , but it seems the permission can't be
requestPermissionsrequested by itself, resulting inPERMISSION_DENIED.On Android 10 it has to be done in combination with eitherACCESS_COURSE_LOCATIONorACCESS_FINE_LOCATION, otherwise the "Allow all the time" option won't be presented, yet those permissions are confusingly labeled "access approximate/precise location only in the foreground". On Android 11 it seems one of those "foreground" has to be granted in a separaterequestPermissionsprior, even if only "background" is actually used. -
The requesting location permissions documentation say that a foreground service will retain access when placed in the background, e.g. by a Home button tap, but the declaration form documentation say such "access to location is considered in the background"!?
-
The declaration form documentation also say a "foreground service" can use the "while in use" (foreground) permission if the "use has been initiated as a continuation of an in-app user-initiated action, and is terminated immediately after the intended use case of the user-initiated action is completed", but what if a
BOOT_COMPLETEDbroadcast,AlarmManageror some other non user-initiated event starts the foreground service usage? -
What should the prominent in-app disclosure include if the app doesn't collect nor share any data, it just do what the permission dialog already say, i.e. "access"? And how do i know which features to include in the disclosure when the API documentation doesn't even tell which actually use it, except the GMS Geofencing API?
I've looked into this recently, and what I noted down is
-
it's an install-time permission; you do not request it at runtime with
requestPermissions -
"On Android 11 (API level 30) and higher, if your app starts a foreground service while running in the background," the service cannot access location, unless the user has granted the ACCESS_BACKGROUND_LOCATION permission to your app.
-
So, let's say a user of your app presses a button, and it starts a foreground service that requires location access. For that, you wouldn't need this permission, because you start the service while the app is not in the background.
-
An app is considered to be running in the background as long as each of the following conditions are satisfied:
-
None of the app's activities are currently visible to the user.
-
The app isn't running any foreground services that started while an activity from the app was visible to the user.
-
-
As I understand it, as long as you start a foreground service while the app is in the foreground, you don't need this permission, because the user will already have permitted foreground access to their location, f.e. with
ACCESS_FINE_LOCATION
This is my take on it, but I might be wrong.
Oh and if you end up needing this permission after all, you also have to add android:foregroundServiceType="location" to your service in the manifest.
Foreground service may work without background permission obviously. That includes nested triggered events like repeating AlarmManager alerts and anything launched by its activity - as long as the foreground service exist in form of notification.
The situation where you need it is when the launch was triggered by remote notification like FCM (in case if the service was reanimated after being killed in doze mode or low memory or phone long inactivity or reboot or whatever). This is extremely useful functionality when continuous tracking is mandatory but other means of communications are limited or impossible. After all your server may as well send a email to the user to notify their service is down after their location wasn't updated for a while.
edit: BOOT_COMPLETED launch is also considered "background". User has to launch foreground service via apps interface i.e. activity for it to be truly "foreground". A bit counter-intuitive.