检测到权限可以被请求或被永久拒绝

时间:2018-06-01 08:36:07

标签: android permissions android-permissions

场合
我的一个片段访问相机。所以当然我需要首先检查我的活动中的权限,然后再重定向到它。如果用户拒绝该权限,则活动完成并将其重定向到他所在的上一个活动 此外,我想在活动开始时显示一个不同的片段,并检测到该权限被永久拒绝。 (Android权限对话框中的小复选框“Never ask again”)

问题
我找不到正确的检测方法,只是一次拒绝了许可,或者上次检查了“永不再问”复选框并永久拒绝了许可。
请记住,我不想知道在onRequestPermissionsResult回调中。如果当前授予,拒绝或永久拒绝许可,我需要在onCreate of my Activity中知道。

我尝试了什么
ActivityCompat#shouldShowRequestPermissionRationale似乎发现过去是否拒绝了许可。如果它只被拒绝一次而不是永久性,它也会返回true。

PermissionChecker#checkPermission()似乎没有注意到永久和只有一次拒绝许可状态之间的任何区别。

问题
是否有任何方法可以检测,是否仍然可以请求许可,或者是否被永久拒绝?

6 个答案:

答案 0 :(得分:5)

  

是否有任何方法可以检测到权限是否被拒绝但是可以   仍被请求或是否被永久拒绝?

不幸的是,当用户选择" 从不再问及"

时,没有正式的API可用于检测权限是否被永久拒绝

有一项工作使用shouldShowRequestPermissionRationale。创建一个默认值为false的SharedPreference,并在其中存储由shouldShowRequestPermissionRationale返回的值。在更新值之前,请检查值集是否为true。如果是true,则不要更新。

每当您想要检查权限时,请获取SharedPreference的值和shouldShowRequestPermissionRationale返回的当前值。如果shouldShowRequestPermissionRationale返回falseSharedPreference的值为true,则可以推断用户已选择Never ask again

您可以参考我描述此方法的blog

答案 1 :(得分:0)

您可以通过

检查权限
if (permissionStatus.getBoolean(Manifest.permission.CALL_PHONE, false)){}

通常我会使用以下内容检查权限,

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {

   if (ActivityCompat.shouldShowRequestPermissionRationale(TrackActivity.this, Manifest.permission.CALL_PHONE)) {
                ActivityCompat.requestPermissions(TrackActivity.this, new String[]{Manifest.permission.CALL_PHONE}, EXTERNAL_STORAGE_PERMISSION_CONSTANT);
       } else if (permissionStatus.getBoolean(Manifest.permission.CALL_PHONE, false)) {

       } else {
                ActivityCompat.requestPermissions(TrackActivity.this, new String[]{Manifest.permission.CALL_PHONE}, EXTERNAL_STORAGE_PERMISSION_CONSTANT);
       }
            SharedPreferences.Editor editor = permissionStatus.edit();
            editor.putBoolean(Manifest.permission.CALL_PHONE, true);
            editor.apply();
   }

答案 2 :(得分:0)

您可以使用Dexter库,该库使处理android权限更加容易。我这样解决了这个问题:

private void checkUserPermission() {
    Dexter.withActivity(this)
            .withPermissions(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.CALL_PHONE,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.CAMERA
            ).withListener(new MultiplePermissionsListener() {
        @Override
        public void onPermissionsChecked(MultiplePermissionsReport report) {
            //check if all permission are granted
            if (report.areAllPermissionsGranted()) {
                initSocket();
            } else {
                List<PermissionDeniedResponse> responses = report.getDeniedPermissionResponses();
                StringBuilder permissionsDenied = new StringBuilder("Permissions denied: ");
                for (PermissionDeniedResponse response : responses) {
                    permissionsDenied.append(response.getPermissionName()).append(" ") ;
                }
                showInfoMessageToast(permissionsDenied.toString());
            }

            if (report.isAnyPermissionPermanentlyDenied()) {
                //permission is permanently denied navigate to user setting
                AlertDialog.Builder dialog = new AlertDialog.Builder(HomeActivity.this)
                        .setTitle("Need Permissions")
                        .setMessage("This application need to use some permissions, " +
                                "you can grant them in the application settings.")
                        .setPositiveButton("GOTO SETTINGS", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                dialogInterface.cancel();
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                Uri uri = Uri.fromParts("package", getPackageName(), null);
                                intent.setData(uri);
                                startActivityForResult(intent, 101);
                            }
                        })
                        .setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                dialogInterface.cancel();
                            }
                        });
                dialog.show();

            }
        }

        @Override
        public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
            token.continuePermissionRequest();
        }
    })
            .onSameThread()
            .check();

}

以这种方式创建导入后

import com.karumi.dexter.Dexter;

针对您要实现的目标进行调整,应该可以解决您的问题。

答案 3 :(得分:0)

shouldShowRequestPermissionRationale根据先前权限请求中的用户首选项返回true或false。

如果用户刚刚被拒绝许可(不是永远),则shouldShowRequestPermissionRationale将返回true。 如果永远拒绝许可,则返回false。 诀窍在于,即使是用户允许的权限,shouldShowRequestPermissionRationale也会返回false

因此,我们可以结合两个条件来选择是否再次选择“不询问”。

因此,如果用户未获得许可,并且shouldShowRequestPermissionRationale返回false,则意味着用户选择不再询问该许可。

答案 4 :(得分:0)

要检测用户是否被永久拒绝该许可,我们不需要使用任何其他逻辑

if (ActivityCompat.shouldShowRequestPermissionRationale(UserEditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)){
                // not permanently denied 
            }
            else {
               // permanently denied 
            }

就是这样。

答案 5 :(得分:0)