Marshmallow的运行时权限

12

一种新的、很棒的安全功能是运行时权限

我正在试着理解它并为此制作一个演示,但是有一个问题困扰着我,即当我用对话框处理用户权限时该怎么处理“不再询问”。

如何处理“不再询问”?

enter image description here

假设我的应用程序必须使用位置/联系人信息,但是用户拒绝了它,并勾选了“不再询问”选项。

我该怎么办呢?并非所有的用户都能理解这个区域是必填项。

有什么建议吗?


我已经为此创建了库。它可以通过简单的步骤轻松使用。https://github.com/Kishanjvaghela/Ask-Permission - Kishan Vaghela
尝试一下,它可能有效。https://dev59.com/J1wX5IYBdhLWcg3w-Thv#41221852 - Bipin Bharti
4个回答

5

首先,您需要在您的Activity中实现OnRequestPermissionsResultCallback监听器接口,这是ActivityCompat类提供的。然后,重写void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)方法,以检查用户是否允许或拒绝权限。

您可以像这样实现。在这里,我检查了WRITE_EXTERNAL_STORAGE权限的访问:

int REQUEST_STORAGE = 1;

private void checkPermissions() {
    if (hasStoragePermissionGranted()) {
        // you can do whatever you want
    } else {
        requestPermission();
    }
}

public boolean hasPermissionGranted(){
        return  ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
}

public void requestPermission() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
        ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_STORAGE);
    }
}

当用户从运行时权限对话框中允许或拒绝权限时,onRequestPermissionsResult()方法将被调用。

您还可以处理用户已选中“不再询问”运行时权限对话框的情况。为此,您可以显示Snackbar或按钮,以将用户重定向到您的应用程序设置页面,因为在用户勾选“不再询问”后,您无法显示权限对话框。

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {

        if (requestCode == REQUEST_STORAGE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               //Storage permission is enabled
               canSendAttachments = true;
               systemLogsCheckbox.setEnabled(true);
            } else if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivtity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                //User has deny from permission dialog
                Snackbar.make(mainLayout, getResources().getString("Please enable storage permission"),
                        Snackbar.LENGTH_INDEFINITE)
                        .setAction("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                ActivityCompat.requestPermissions(MainActivity.this, {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_STORAGE);
                            }
                        })
                        .show();
            } else {
                // User has deny permission and checked never show permission dialog so you can redirect to Application settings page
                Snackbar.make(mainLayout, getResources().getString("Please enable permission from settings"),
                        Snackbar.LENGTH_INDEFINITE)
                        .setAction("OK", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Intent intent = new Intent();
                                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", MainActivity.this.getPackageName(), null);
                                intent.setData(uri);
                                startActivity(intent);
                            }
                        })
                        .show();
            }
        }
    }

在这里,我使用了Snackbar来向用户显示有关权限的相关信息,而mainLayoutActivity主布局的ID。

希望对您有所帮助。


谢谢您的建议,我已经实现了它,但我的问题是,如果用户点击“拒绝”但我的应用程序需要位置信息,我该怎么办?如何说服用户? - Vishal Patel
您向用户解释应用程序为何需要此权限。您还说明了如果用户不允许权限会发生什么情况。 - Rajesh Jadav
1
@VishalPatel 是的,如果必须要权限,应用程序将无法工作。 - Rajesh Jadav
1
如果用户选择“不再询问”,则您的权限已被永久拒绝,并且只能通过Android设置启用。如果该权限对您的应用程序至关重要,建议您在请求权限之前使用“引导”消息。您可以显示一个引导对话框(或全屏视图),让用户了解为什么需要该权限以及如果未授予该权限会发生什么。之后,您可以请求该权限。请查看此库https://github.com/aitorvs/allowme,该库还实现了简单的引导对话框。 - Aitor Viana
我已经为此创建了一个库。它可以通过简单的步骤轻松使用。https://github.com/Kishanjvaghela/Ask-Permission - Kishan Vaghela

2

我创建了一个,可以帮助您处理所有的权限。您可以在这里找到它:

PermissionHelper


回答您的问题:

为了知道用户是否勾选了“不再显示”,您需要检查两个条件:如果权限被拒绝无需解释,如果这两个条件都返回**true**,那么该权限将不再可用,唯一的解决方案是打开设置屏幕。

P.S:我创建的库可以为您处理所有这些情况,并返回回调以让您决定下一步要做什么!该库有两种实现方式:

  1. 手动实现(这意味着您必须在活动中实现回调并监听从库返回的回调)。
  2. 让库为您请求权限,它也会返回一个回调,让您决定当权限被永久拒绝时发生什么。

1

当用户选择“不再询问”时,请打开您的应用程序设置。

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, REQUEST_PERMISSION_SETTING);

我演示如何处理运行时权限的例子:
https://github.com/henrychuangtw/RuntimePermission

0

使用Dexter

或者

使用PermissionsDispatcher:

步骤1:使用PermissionsDispatcher库,作者是hotchemi(该库基于注释,易于使用且文档完善)

步骤2:您需要提供4个带注释的方法之一是@OnNeverAskAgain(Manifest.permission.[permission_you_want]),如下所示

@OnNeverAskAgain(Manifest.permission.[permission_you_want])
void showNeverAsk() {  
   // handle here
}  

这里是示例


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接