问题描述
从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);