【问题标题】:Android M - failed to check runtime permissionAndroid M - 未能检查运行时权限
【发布时间】:2016-06-30 10:56:53
【问题描述】:

我刚刚开始在 Android M 上使用运行时权限。我在 AndroidManifest.xml 中声明了 CAMERA、READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE

问题是如果用户转到设置并明确关闭如下权限,我无法检查我的应用是否启用了相机或存储权限

我使用这个 sn-p 来检查我的应用是否有特定权限:

public static boolean hasPermission(Context c, String permission) {
    if (Build.VERSION.SDK_INT >= 23) {
        return ContextCompat.checkSelfPermission(c, permission) == PackageManager.PERMISSION_GRANTED;
    }
    return true;
}

令人惊讶的是,即使我在“设置”中将它们关闭,每次检查相机和存储权限都会返回 true(已授予)。

我的targetSdkVersion 23 岁

这是 Google 提供的预期行为吗?我环顾网络,仍然找不到任何文档说明处理显式调用的权限。

【问题讨论】:

  • 你的targetSdkVersion是什么?
  • 我的目标是 SDK 23
  • 您在哪个版本的 Android 上进行测试?现在,您只能在 23+ 时致电 checkSelfPermission()ContextCompat.checkSelfPermission() 可以在任何版本的 Android 上调用(至少回到 API 级别 4),所以我将删除 if 检查。您的屏幕截图看起来像是 API 级别 23 设备,在这种情况下,如果您的 targetSdkVersion 是 23,我无法解释您的症状。
  • 我在运行 Android M 的设备上进行了测试,我确实在我的代码上放置了断点来跟踪它,它运行了 ContextCompat.checkSelfPermission() 函数
  • 我目前也面临同样的问题(权限检查始终显示即使在权限被撤销后也已授予),您最近找到解决方案了吗?

标签: android permissions android-manifest android-6.0-marshmallow


【解决方案1】:

再次检查 onRestart() 中的权限。

@TargetApi(Build.VERSION_CODES.M)
    @Override
    protected void onRestart() {
        super.onRestart();
        checkForPermission();
    }


@TargetApi(Build.VERSION_CODES.M)
    private void checkForPermission() {
        int permissionCheck = checkSelfPermission(Manifest.permission.READ_CONTACTS);
        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "Granted");
        } else {
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_CONTACTS)) {
                Log.d(TAG, "Contacts Permission Required!!");
                createSnackbar("Contacts Permission Required!!", "Try Again");
            }
            ActivityCompat.
                    requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, REQUEST_CONTACT);

        }
    }

查看此链接以获取更多信息: https://github.com/sagarjogadia28/PermissionSample/

【讨论】:

  • 我运行了检查,转到设置以关闭权限,然后返回我的应用程序再次运行检查。我不认为这是一个有效的答案
  • 您必须再次检查权限
  • 我不明白你的意思,我检查了设置何时打开,并在设置关闭时再次检查。在我遇到的每种情况下,它总是返回 true(已授予权限)
  • onRestart() --> onStart() --> onResume() 在设置中按下后退按钮并且我们的应用程序对用户可见时被调用,因此我们需要再次检查权限是否有在 onRestart() 方法中是否被授予。
  • Sagar 是正确的。在正常情况下,您的应用应该按照他描述的方式运行。
【解决方案2】:

您必须更改 targetSDKVersion 因为

您应该为低于 23 的任何 targetSdkVersion 获得 PERMISSION_GRANTED,即使用户在“设置”中关闭了该权限组。建议您彻底卸载应用,将 targetSdkVersion 设置为 23,然后再试一次。

你可以查看这个link

【讨论】:

    【解决方案3】:

    你需要做不同的事情。

    首先,请求允许您尝试执行的操作。示例相机:

    //This is a class variable
    private final static int MY_PERMISSIONS_REQUEST_CAMERA = 1;
    
    ...
    
    // before use camera:
    // check permissions for CAMERA
    if (ContextCompat.checkSelfPermission(ActivityName.this,
            Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {
    
        //request permission
        ActivityCompat.requestPermissions(ActivityName.this,
                new String[]{Manifest.permission.CAMERA},
                MY_PERMISSIONS_REQUEST_CAMERA);
    
    } else {
        //permissions granted, do wahtever with camera
        functionToHandleCamera();
    }
    

    然后您需要处理用户响应:允许或拒绝。所以重写 onRequestPermissionsResult 方法

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_CAMERA: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //permissions granted, do wahtever with camera
                    functionToHandleCamera();
    
                } else {
                    // permission denied
                    Toast msg = Toast.makeText(this, "PERMISSIONS NEEDED", Toast.LENGTH_LONG);
                    msg.setGravity(Gravity.CENTER, 0, 0);
                    msg.show();
                }
                return;
            }
    
        }
    }
    

    更多信息: https://developer.android.com/training/permissions/requesting.html

    编辑:如果你只想检查权限是否被授予,你只需要我写的代码的第一部分。

    【讨论】:

    • 是的,我明白了,我首先需要检查我的许可是否被授予,如果没有,我会要求它。不幸的是,正如我在问题中所说,返回的结果始终为真(已授予),因此我的代码不会运行到请求权限部分
    【解决方案4】:

    将此添加到您的onCreate 活动方法中:-

    if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
    
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {
    
                // 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 {
    
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        0);
    
            }
        }
    

    override这个方法:-

    @Override
    
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 0: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
    
                } else {
    
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }
    
            // other 'case' lines to check for other
            // permissions this app might request
        }
    }
    

    【讨论】:

    • 我将评论这个答案,就像我评论上面的答案一样。并不是我不知道如何请求权限,而是它总是返回 true 表示已授予权限,那么我到底如何跳转到请求您上面引用的权限的代码块?
    猜你喜欢
    • 1970-01-01
    • 2016-03-25
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 2016-07-16
    • 1970-01-01
    • 2015-08-22
    • 2017-07-27
    相关资源
    最近更新 更多