Android 11 users can’t grant background location permission?

爷,独闯天下 提交于 2021-01-20 16:44:29

问题


As of Android 11, apps targeting SDK 30+ will not show a user an option to grant background location permission to an app, instead it requires users to go to a settings page. How do we bring a user to the proper settings page?

When a feature in your app requests background location on a device that runs Android 11 or higher, the system dialog doesn't include a button to enable background location access. In order to enable background location access, users must set the Allow all the time option for your app's location permission on a settings page, as described in the guide on how to Request background location.

https://developer.android.com/about/versions/11/privacy/location#change-details

The user-visible label of the settings option that grants background location (for example, Allow all the time in figure 3). You can callgetBackgroundPermissionOptionLabel() to get this label. The return value of this method is localized to the user's device language preference.

https://developer.android.com/training/location/permissions#request-location-access-runtime

While Android provides a new API to get this settings page label, there is no documented API to bring up this settings page directly. The closest you can come is to bring up the app-specific settings page as described below. From there, the user must perform at least two taps to drill down to Permissions -> Location to enable background access. This is an onerous process that many users will fail to complete.

The lack of an API to bring up a settings page has been documented for a long time in this question, but is far more important as of the release of Android 11, as there is no other way of granting background permission.

How to programmatically open the Permission Screen for a specific app on Android Marshmallow?

It is possible to bring the user to the proper settings page the very first time the user is asked using code like this: requestPermissions(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION), PERMISSION_REQUEST_BACKGROUND_LOCATION). This will work only once. If the user denies the permission (or even accidentally hits back or leaves the screen without granting), this will never work again, and the user must manually drill-down in settings as described above.

Is there there really no way for an app to help users grant background location permission after an initial denial other than to instruct them to go hunting for the right page in Settings?

Am I missing something? If not, isn’t this a major Android 11 usability problem?

A full example of code needed to trigger the proper settings page in a first time prompt, but the inability to do it ever again is here:

        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if (checkSelfPermission(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
                != PackageManager.PERMISSION_GRANTED
            ) {
                if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
                    val builder =
                        AlertDialog.Builder(this)
                    builder.setTitle("This app needs background location access")
                    builder.setMessage("Please grant location access so this app can detect beacons in the background.")
                    builder.setPositiveButton(android.R.string.ok, null)
                    builder.setOnDismissListener {
                        requestPermissions(
                            arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),
                            PERMISSION_REQUEST_BACKGROUND_LOCATION
                        )
                    }
                    builder.show()
                } else {
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                        val builder =
                            AlertDialog.Builder(this)
                        builder.setTitle("Functionality limited")
                        builder.setMessage("Since background location access has not been granted, this app will not be able to discover beacons in the background.  Please go to Settings -> Applications -> Permissions and grant background location access to this app.")
                        builder.setPositiveButton(android.R.string.ok, null)
                        builder.setOnDismissListener {
                            val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                            val uri: Uri = Uri.fromParts("package", packageName, null)
                            intent.data = uri
                            // This will take the user to a page where they have to click twice to drill down to grant the permission
                            startActivity(intent)
                        }
                        builder.show()
                    }
                }
            }
        } else {
            if (!shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
                requestPermissions(
                    arrayOf(
                        Manifest.permission.ACCESS_FINE_LOCATION
                        /*Manifest.permission.ACCESS_BACKGROUND_LOCATION*/
                    ),
                    PERMISSION_REQUEST_FINE_LOCATION
                )
            } else {
                val builder = AlertDialog.Builder(this)
                builder.setTitle("Functionality limited")
                builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons.  Please go to Settings -> Applications -> Permissions and grant location access to this app.")
                builder.setPositiveButton(android.R.string.ok, null)
                builder.setOnDismissListener {
                    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                    val uri: Uri = Uri.fromParts("package", packageName, null)
                    intent.data = uri
                    // This will take the user to a page where they have to click twice to drill down to grant the permission
                    startActivity(intent)
                }
                builder.show()
            }
        }



回答1:


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.



来源:https://stackoverflow.com/questions/64246883/android-11-users-can-t-grant-background-location-permission

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!