Android shouldShowRequestPermissionRationale有错误吗?

时间:2016-09-28 05:27:51

标签: android android-permissions

我认为有一个错误shouldShowRequestPermissionRationale

代码是......

@Override
protected void onResume() {
    super.onResume();
    if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED &&
            ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) {
        if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) ||
                ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
            new AlertDialog.Builder(this)....show();
    } else {
        // do something...
}

首先安装应用程序,我们不允许这样做。因此,当调用onResume时,应出现AlertDialog。但它似乎没有......

如果我们进入应用程序的设置,并允许该权限。所以我们播放应用代码(// do something)。再次,我们进入应用程序的设置,拒绝许可。然后我们重启应用程序,出现AlertDialog。

为什么应用程序会像这样运行?

4 个答案:

答案 0 :(得分:4)

来自开发人员文档:

<强> shouldShowRequestPermissionRationale()

  

如果应用先前已请求此权限且用户拒绝了该请求,则此方法返回true。

     

注意:如果用户过去拒绝了权限请求并在权限请求系统对话框中选择了“不再询问”选项,则此方法返回false。

问题是您在使用

之前尚未获得许可
 ActivityCompat.requestPermissions();

因此它没有显示对话框。

当您手动授予“设置”权限或拒绝权限时,它会认为您拒绝了该权限,这就是为什么它会显示“警报”对话框。

答案 1 :(得分:1)

使用Gmail API并在其示例代码中找到有关Android权限的其他选项。您可能希望使用Google自己提供的 EasyPermissions ,如上所述,&#34;简化Android M系统权限&#34;。

答案 2 :(得分:0)

检查此实施。对我来说工作很好。基本上你检查checkPermissions()方法中传递权限列表的权限。您在onRequestPermissionsResult()上检查权限请求的结果。该实现允许您解决用户选择&#34;再也不会再问及#34;或不。在此实现中,如果se选择&#34;再也不再询问&#34;,该对话框可以选择将他带到App Settings Activity。

所有这些代码都在我的片段中。我认为创建一个专门的类来做这件事会更好,比如PermissionManager,但是我不确定。

/**
     * responsible for checking if permissions are granted. In case permissions are not granted, the user will be requested and the method returns false. In case we have all permissions, the method return true.
     * The response of the request for the permissions is going to be handled in the onRequestPermissionsResult() method
     * @param permissions list of permissions to be checked if are granted onRequestPermissionsResult().
     * @param requestCode request code to identify this request in
     * @return true case we already have all permissions. false in case we had to prompt the user for it.
     */
    private boolean checkPermissions(List<String> permissions, int requestCode) {
        List<String> permissionsNotGranted = new ArrayList<>();
        for (String permission : permissions) {
            if (ContextCompat.checkSelfPermission(getActivity(), permission) != PackageManager.PERMISSION_GRANTED)
                permissionsNotGranted.add(permission);
        }

        //If there is any permission we don't have (it's going to be in permissionsNotGranted List) , we need to request.
        if (!permissionsNotGranted.isEmpty()) {
            requestPermissions(permissionsNotGranted.toArray(new String[permissionsNotGranted.size()]), requestCode);
            return false;
        }
        return true;
    }

    /**
     * called after permissions are requested to the user. This is called always, either
     * has granted or not the permissions.
     * @param requestCode  int code used to identify the request made. Was passed as parameter in the
     *                     requestPermissions() call.
     * @param permissions  Array containing the permissions asked to the user.
     * @param grantResults Array containing the results of the permissions requested to the user.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case YOUR_REQUEST_CODE: {
                boolean anyPermissionDenied = false;
                boolean neverAskAgainSelected = false;
                // Check if any permission asked has been denied
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                        anyPermissionDenied = true;
                        //check if user select "never ask again" when denying any permission
                        if (!shouldShowRequestPermissionRationale(permissions[i])) {
                            neverAskAgainSelected = true;
                        }
                    }
                }
                if (!anyPermissionDenied) {
                    // All Permissions asked were granted! Yey!
                    // DO YOUR STUFF
                } else {
                    // the user has just denied one or all of the permissions
                    // use this message to explain why he needs to grant these permissions in order to proceed
                    String message = "";
                    DialogInterface.OnClickListener listener = null;
                    if (neverAskAgainSelected) {
                        //This message is displayed after the user has checked never ask again checkbox.
                        message = getString(R.string.permission_denied_never_ask_again_dialog_message);
                        listener = new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //this will be executed if User clicks OK button. This is gonna take the user to the App Settings
                                startAppSettingsConfigActivity();
                            }
                        };
                    } else {
                        //This message is displayed while the user hasn't checked never ask again checkbox.
                        message = getString(R.string.permission_denied_dialog_message);
                    }
                    new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme)
                            .setMessage(message)
                            .setPositiveButton(getString(R.string.label_Ok), listener)
                            .setNegativeButton(getString(R.string.label_cancel), null)
                            .create()
                            .show();
                }
            }
            break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * start the App Settings Activity so that the user can change
     * settings related to the application such as permissions.
     */
    private void startAppSettingsConfigActivity() {
        final Intent i = new Intent();
        i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.setData(Uri.parse("package:" + getActivity().getPackageName()));
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
        i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        getActivity().startActivity(i);
    }

答案 3 :(得分:-1)

了解运行时权限的控制流程

if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_DENIED &&
            ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_DENIED) {
        if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) ||
                ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {

           //Block1

        } else {

           //Block2

        }
}else{
//Do something here
}

有时 Block1 Block2 将被调用的情况 案例1:当我们第一次尝试显示权限弹出窗口时(权限对话框不会显示再也不会再询问复选框) Block2

案例2:如果用户第一次拒绝,如果您从下次(第二次以后)调用相同的代码 Block1 将是调用并显示对话框从不再询问复选框。

案例3:如果您检查再也不要询问那么从那时起如果您执行相同的代码,它将调用 Block2 但不直接显示对话框/弹出窗口会自动触发 DENY onRequestPermissionsResult方法会以拒绝方式触发。