混淆应该显示许可请求的理由

Alt*_*iir 6 android android-permissions android-6.0-marshmallow

我对 android M 及更高版本的新权限模型有点好奇,尤其是“shouldShowRequestPermissionRationale()”方法。在文档中

为了帮助查找用户可能需要解释的情况,Android 提供了一个实用方法 shouldShowRequestPermissionRationale()。如果应用程序先前已请求此权限并且用户拒绝了该请求,则此方法返回 true。

注意:如果用户过去拒绝了权限请求并在权限请求系统对话框中选择了不再询问选项,则此方法返回 false。如果设备策略禁止应用拥有该权限,该方法也会返回 false。

好的,用户肯定拒绝了权限。现在在同一页面的代码片段中:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {

        // Show an expanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);

        // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}
Run Code Online (Sandbox Code Playgroud)

混乱来自 else 块,它返回 false 然后用户拒绝了该权限,这意味着我们不断向用户询问他拒绝的权限,这与最佳实践相矛盾

我的问题是;我们如何实现一个好的逻辑来处理这一切?

Mer*_*ost 1

对我来说它的工作原理是这样的:

if (cameraPermissionState.hasPermission) {
    // Camera permissions are given, may proceed

} else if (cameraPermissionState.shouldShowRationale.not()) {
    // We can ask user for permission

    cameraPermissionState.launchPermissionRequest()
 else {
    // We are unable to ask user anymore or he has declined the permission
    // Open app settings for user to get permission manually

    context.openAppSettings()
 }
Run Code Online (Sandbox Code Playgroud)

我的openAppSettings扩展看起来像这样,以防万一您需要它:

fun Context.openAppSettings() {

    val intent = Intent(ACTION_APPLICATION_DETAILS_SETTINGS).apply {
        data = Uri.fromParts("package", packageName, null)
        addCategory(CATEGORY_DEFAULT)
        addFlags(FLAG_ACTIVITY_NEW_TASK)
        addFlags(FLAG_ACTIVITY_NO_HISTORY)
        addFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
    }

    startActivity(intent)
}
Run Code Online (Sandbox Code Playgroud)