Tirafesi
Tirafesi

Reputation: 1479

Android Permission Request Error

I'm trying to get the last known location using google api.

I'm getting the error "Call requires permissions which may be rejected..."

However, I've already asked for the permissions in runtime, so I don't know why the error is still showing...

Here's what I've done:

/** Value to match on callback of request permissions response */
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 1;


/** GoogleApiClient */
private GoogleApiClient googleApiClient = null;


/** Last known location */
private Location lastLocation = null;


@Override
protected void onCreate(Bundle savedInstanceState) {

    // ...

    // Create a GoogleApiClient instance
    googleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .enableAutoManage(this, this)
            .addApi(LocationServices.API)
            .build();
}


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

    switch (requestCode) {

        case MY_PERMISSIONS_REQUEST_LOCATION: {

            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay!
                if (permissions.length == 1 &&
                    permissions[0] == Manifest.permission.ACCESS_FINE_LOCATION) {

                    // ERROR STILL SHOWING HERE!
                    lastLocation = LocationServices.FusedLocationApi.getLastLocation(
                            googleApiClient);
                }


            } else {

                // permission denied, boo!
            }
            break;
        }

        default:
            break;

    }
}


@Override
public void onConnected(@Nullable Bundle bundle) {

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {

        // NO ERROR HERE, IT'S FINE
        lastLocation = LocationServices.FusedLocationApi.getLastLocation(
                googleApiClient);
    } else {

        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                MY_PERMISSIONS_REQUEST_LOCATION);

    }
}


@Override
public void onConnectionSuspended(int i) {
    // do nothing
}


@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    // An unresolvable error has occurred and a connection to Google APIs
    // could not be established. Display an error message, or handle
    // the failure silently
    Toast toast = Toast.makeText(this, getText(R.string.google_api_connection_error), Toast.LENGTH_LONG);
    toast.show();
}

As you can see, this is what I want to do:

lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);

Why do I still get the error and how can I fix this?

Thanks in advance!

Upvotes: 0

Views: 959

Answers (1)

CommonsWare
CommonsWare

Reputation: 1007494

There are two ways to fix any complaint from Lint:

  1. Change your code to make Lint happy

  2. Tell Lint to leave you alone, typically via a @SuppressLint annotation (though there are alternatives in some cases, such as @TargetApi)

Most times, the right answer is to change your code. So, for example, if Lint complains that you have used a string in a place where a string resource might be more appropriate, there is a very good chance that the right answer is to create a string resource.

The reason why Lint is fairly good overall is that most of its checks deal with an individual Java statement.

In your particular case, Lint is triggered by an individual Java statement (your getLastKnownLocation() call), but it also needs to examine what code paths can lead to that statement, and whether you are ensuring that you hold the proper runtime permission for all of those call paths. Frankly, Lint is not very good at this. As a result, this particular Lint check throws more "false positives" than I like.

There may be a way to reorganize your code such that Lint is happy. However:

  • That is not guaranteed, both for today's Lint and all possible future editions of Lint

  • The resulting code may be more confusing to you, even if it is less confusing to Lint

  • Your code may be fine as it stands

@SuppressLint basically says "I know what I am doing, quit complaining and leave me alone". Sometimes, it is the only way to get Lint to stop complaining about perfectly-valid code.

In your particular case, test your code. If the code works both when you do and do not hold the required runtime permission, then your code is fine, and @SuppressLint is a valid approach.

Upvotes: 1

Related Questions