Android 11用户无法授予后台位置权限?

问题描述

从Android 11开始,面向SDK 30+的应用不会向用户显示向应用授予后台位置权限的选项,而是需要用户转到设置页面我们如何将用户带到正确的设置页面

当应用程序中的功能请求运行Android 11或更高版本的设备上的后台位置时,系统对话框将不包含用于启用后台位置访问的按钮。为了启用后台位置访问,用户必须在设置页面上为应用的位置权限设置“允许所有时间”选项,如有关如何请求后台位置的指南中所述。

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

设置位置的用户可见标签授予后台位置(例如,图3中的所有时间都允许)。您可以调用getBackgroundPermissionoptionLabel()获得此标签。此方法的返回值被本地化为用户的设备语言首选项。

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

尽管Android提供了新的API来获取此设置页面标签,但没有文档说明的API可直接显示此设置页面。您可以最接近的是按如下所述打开应用程序特定的设置页面。从那里开始,用户必须至少执行两次轻击才能深入到“权限”->“位置”以启用后台访问。这是一个繁琐的过程,许多用户将无法完成。

这个问题已经有很长时间的记录了,因为缺少API不能显示设置页面,但是从发布Android 11开始,这一点更为重要,因为没有其他方法可以授予后台权限。 / p>

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

使用以下代码requestPermissions(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION),PERMISSION_REQUEST_BACKGROUND_LOCATION),可以在第一次询问用户时将用户带到正确的设置页面。这将只工作一次。如果用户拒绝该许可(甚至意外地回退或未经授权就退出屏幕),则此操作将永远无法进行,并且用户必须如上所述手动向下钻取设置。

除了指示用户去“设置”中的正确页面之外,应用是否真的没有办法帮助用户授予后台位置许可?

我错过了什么吗?如果不是,这不是Android 11的主要可用性问题吗?

在第一次提示时触发正确的设置页面所需的完整代码示例,但此处无法再次执行:

        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",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()
            }
        }


解决方法

@Stephen Ruda的回答的积分

我遇到了完全相同的问题。我同意这对于任何需要后台位置权限的开发人员来说都是一个问题。我想为其他读者添加额外的注释:

(1) 在 API 30+ 上,在请求后台位置权限之前,您首先需要基本位置权限 - 否则,它根本不会进入权限屏幕。

(2) 当您请求后台位置权限并将它们发送到权限请求屏幕时,如果用户只点击后退按钮,它只会“锁定”用户。如果他们点击任何选项然后返回请求将再次工作。

,

它不应该有任何不同,但这对我每次都有效(不仅仅是一次):

ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION},REQUEST_BACKGROUND_LOCATION_PERMISSION);

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...