Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/190.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 检测是否可以请求权限或永久拒绝权限_Android_Permissions_Android Permissions - Fatal编程技术网

Android 检测是否可以请求权限或永久拒绝权限

Android 检测是否可以请求权限或永久拒绝权限,android,permissions,android-permissions,Android,Permissions,Android Permissions,形势 我的一个碎片进入了摄像机。因此,在重定向到活动之前,我当然需要首先检查活动中的权限。如果用户拒绝该权限,则活动将完成,并将他重定向到他所在的上一个活动。 此外,当活动启动并检测到权限被永久拒绝时,我想显示一个不同的片段。(android权限对话框上的小复选框“永不再次询问”) 问题 我找不到合适的方法来检测权限是否只被拒绝了一次,或者是否上次选中了“永不再次询问”复选框并永久拒绝了权限。 请记住,我不想在onRequestPermissionsResult回调中知道这一点。我需要在创建我的

形势
我的一个碎片进入了摄像机。因此,在重定向到活动之前,我当然需要首先检查活动中的权限。如果用户拒绝该权限,则活动将完成,并将他重定向到他所在的上一个活动。
此外,当活动启动并检测到权限被永久拒绝时,我想显示一个不同的片段。(android权限对话框上的小复选框“永不再次询问”)

问题
我找不到合适的方法来检测权限是否只被拒绝了一次,或者是否上次选中了“永不再次询问”复选框并永久拒绝了权限。
请记住,我不想在onRequestPermissionsResult回调中知道这一点。我需要在创建我的活动时知道当前是否授予、拒绝或永久拒绝了权限

我尝试的
ActivityCompat#should show requestPermissionPrincipal
似乎可以检测到该权限过去是否被拒绝。如果它只被拒绝一次而不是被永久拒绝,它也会返回true

PermissionChecker#checkPermission()
似乎没有注意到永久和仅一次被拒绝的权限状态之间的任何区别

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

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

不幸的是,当用户选择“不再询问”时,没有官方API可用于检测权限是否被永久拒绝

有一个解决办法是使用
shouldshowRequestPermissionRegulation
。创建一个默认值为
false
的SharedReference,并将
shouldShowRequestPermissionRegulation
返回的值存储在其中。更新值之前,请检查值集是否为
true
。如果它是
true
,则不要更新它

无论何时要检查权限,请从
SharedReference
获取值,并从
shouldShowRequestPermissionRegulation
返回当前值。如果
shouldshowRequestPermissionPrinciple
返回
false
,但
共享参考
中的值为
true
,则可以推断
不再询问
是用户选择的


您可以参考我的,其中我描述了这种方法。

您可以通过

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();
   }

您可以使用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();

}

将其调整到您想要达到的程度,应该可以解决您的问题。

应该显示请求许可理由
根据用户在上一次权限请求中的偏好返回true或false

如果用户刚刚拒绝了权限(不是永远拒绝)
应该显示requestpermissionrational
将返回
true
。 如果永远拒绝权限,则返回
false
。 诀窍是,即使是用户允许的权限,然后
showledrequestpermissionrationalys理
也会返回
false

因此,我们可以将这两个条件结合起来,以选择“永不再问”选项


因此,如果用户不允许权限,并且
showRequestPermissionRegulation
返回
false
,则表示用户选择不再请求权限。

要检测用户是否被永久拒绝权限,我们不需要任何额外的逻辑,只需使用它即可

if (ActivityCompat.shouldShowRequestPermissionRationale(UserEditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)){
                // not permanently denied 
            }
            else {
               // permanently denied 
            }
就是这样。

此库运行良好:


此外,这篇文章也很有用:

假设这总是有效的,那么“安全”程度如何?shouldShowRequestPermissionRegulation是否没有机会在第一次请求时立即返回true?@Basti基于
shouldShowRequestPermissionRegulation
仅当用户先前拒绝请求时才会返回true。这应该很可靠很好,谢谢。遗憾的是,android没有为此提供API。仍然要通过ofc对该解决方案进行压力测试:D@Basti是啊,那太可悲了。如果你在压力测试中发现了一些问题,如果你没有发现任何复杂的情况,请告诉我,这将是一件非常好的事情
if (ActivityCompat.shouldShowRequestPermissionRationale(UserEditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)){
                // not permanently denied 
            }
            else {
               // permanently denied 
            }