Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

False positive lint permission error even after asking for permission at runtime

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 ?

like image 209
Somesh Kumar Avatar asked Jun 05 '16 13:06

Somesh Kumar


People also ask

How to check if permission is granted or not in android?

To check if the user has already granted your app a particular permission, pass that permission into the ContextCompat. checkSelfPermission() method. This method returns either PERMISSION_GRANTED or PERMISSION_DENIED , depending on whether your app has the permission.

How to request multiple permissions in android?

Just include all 4 permissions in the ActivityCompat. requestPermissions(...) call and Android will automatically page them together like you mentioned. I have a helper method to check multiple permissions and see if any of them are not granted.

What is access_ background_ location?

ACCESS_BACKGROUND_LOCATION. Allows an app to access location in the background. String.


1 Answers

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.

like image 175
F43nd1r Avatar answered Sep 22 '22 17:09

F43nd1r