【问题标题】:False positive lint permission error even after asking for permission at runtime即使在运行时请求许可后也会出现误报 lint 权限错误
【发布时间】:2016-10-05 03:58:23
【问题描述】:

我很难理解 android 使用的运行时权限方法。对于那些正在阅读本文的人,我不是在这里问“如何调用运行时权限”。如果尚未授予权限,我可以显示权限对话框,甚至可以在片段中获得 onRequestPermissionsResult() 的结果。

使用此代码

 if (ContextCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        FragmentCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, RQ_GET_LOCATION);
        Log.e("permission", "asking permission");
        return;
    }
   Log.e("permission", "permission already granted");
   accessLocation();

onRequestPermissionsResult得到结果

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

    switch (requestCode) {
        case RQ_GET_LOCATION:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.e("permission", "onRequestPermissionsResult : permission granted, access location here");
                accessLocation();
            }
            else {
                Log.e("permission", "onRequestPermissionsResult : permission denied");
            }
            break;
    }
}

accessLocation() 内的代码是

 private void accessLocation()
{
    Log.e("permission", "accessing location permission");
    Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    if (mLastLocation != null) {
        userDetail.setLat(String.valueOf(mLastLocation.getLatitude()));
        userDetail.setLat(String.valueOf(mLastLocation.getLongitude()));
    }
    else {
        if (!isLocationEnabled()) {
            mShowAlert();
        }
    }
}

到目前为止一切顺利.. 但困扰我的是,在我的 accessLocation() 方法中,我在线收到误报错误

Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

说的是

调用需要可能被用户拒绝的权限:代码应明确检查权限是否可用(使用checkPermission)或明确处理潜在的SecurityException

我知道当您不检查权限时会出现这种情况。一旦我用@SuppressWarnings("MissingPermission") 注释方法,这个错误就会出现

我不知道当开发人员必须在他们的类中多次调用方法时,他们实际上是如何处理此类错误的。 我必须使用@SuppressWarnings("MissingPermission") 还是? (我不知道)

假设我请求一个权限,就像我在上面的第一个代码块中所做的那样 > 权限对话框弹出 > 用户授予权限 > 流程转到 onRequestPermissionsResult 并且我再次编写用于访问位置的代码,但这也会向我显示错误未检查权限的正错误..

要么我做的很糟糕,要么我认为我误解了权限模型,或者 lint 存在一些错误(我真的不认为这是问题所在)..

我已经研究过this * questionthis studio bug,但我对那里的答案并不满意。

请告诉我我做错了什么?

【问题讨论】:

  • 尝试将您的第一个代码 sn-p 中的 accessLocation() 放在 else 块中,而不是在 if 块中使用 return。 Lint 可能缺少 return,因此无论您是否拥有权限,都认为您正在调用 accessLocation()
  • @CommonsWare 试过了,还是不走运先生。
  • 找到解决办法了吗?
  • @WideFide 不,据我所知这是一个错误。你也面临吗?
  • 没有。我看到你这么问了。我正在回答,希望对您有所帮助。

标签: java android android-permissions


【解决方案1】:

首先:你没有做错任何事。您的代码将按预期工作。


我建议直接取消警告,因为它显然是错误的。


但是,如果您想满足 Lint 要求,您必须将代码重构为以下架构

void doSomething(){
    if(permission granted){
        //do stuff (directly in here, do not delegate this to other methods)
    }else{
        //request permission
    }
}

void onRequestPermissionsResult(...){
    if(permission granted){
        doSomething();
    }
}

是的,如果之前未授予权限,这将导致仔细检查。是的,生成的代码很难阅读。但警告会消失。

运行时权限系统太可怕了,我们对此无能为力。

【讨论】: