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 potentialSecurityException
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 ?
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.
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.
ACCESS_BACKGROUND_LOCATION. Allows an app to access location in the background. String.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With