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

dav*_*ung 26 android location android-permissions android-geofence beacon

从 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 发布时更为重要,因为没有其他方式授予后台权限。

如何以编程方式打开 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", 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()
            }
        }


Run Code Online (Sandbox Code Playgroud)

Vic*_*rte 11

感谢@Stephen Ruda的回答

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

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

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

  • 这对于第一次提示是正确的。但是,我的具体问题是用户未能授予该权限(有意或无意)后会发生什么,并且应用程序希望帮助用户找到正确的权限屏幕以稍后授予权限。据我所知,这是不可能直接链接的。 (3认同)
  • 我经历过第 (2) 项,但不明白发生了什么......现在我知道我不是唯一的一个!谢谢!...顺便说一句,我真的认为谷歌最近把事情搞砸了。 (2认同)