False positive lint permission error even after as

2019-04-06 20:59发布

问题:

I am having hard time understanding runtime permission approach used by android. For those who are reading this, I am not asking here "how to call runtime permission".. i am able to show a permission dialog if it's not already been granted and even get it's result in onRequestPermissionsResult() in fragment.

with this code

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

Getting result in 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;
    }
}

code inside accessLocation() is

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

so far so good.. but what's bothering me is that inside my accessLocation() method i'm getting false positive error on line

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

that says

Call requires permission which may be rejected by user: code should explicitly check to see if permission is available (with checkPermission) or explicitly handle a potential SecurityException

i know this comes when you you don't check for permission. This error goes as soon as i annotate method with @SuppressWarnings("MissingPermission")

i don't know how developers are actually handling such errors when they have to call method at multiple times in their class. either i have to use @SuppressWarnings("MissingPermission") or ? (i don't know)

suppose i request a permission like i am doing in the first code block above > permission dialog pops up > user grants permission > flow goes to onRequestPermissionsResult and again i write code for accessing location but that will also show me a false positive error for not checking permission..

either i'm doing something terrible or i think i misunderstood the permission model or there is some bug with lint (i REALLY don't think this is the problem)..

I've already looked into this stackoverflow question and this studio bug but i am not satisfied with the answers there.

SO PLEASE TELL ME WHAT AM I DOING WRONG ?

回答1:

First off: You are not doing anything wrong. Your code will work just as expected.


I would advise to just suppress the warning, as it is clearly wrong.


However, if you want to fulfill the Lint requirements, you have to refactor your code to the following schema

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

Yes, this will result in a double check if the permission was not granted earlier. Yes, the resulting code is bad to read. But the warning will go away.

The runtime permission system is horrible and there is nothing we can do about it.