1

I am developing a GoogleMap application and thus require the users location. When asking this with the following code:

if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
   // all good, do my thing.
}else{
   ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, this.MY_PERMISSIONS_REQUEST_ACCESS_LOCATION);
   return false;
}

it will prompt the user to deny or allow it. When user Allows the permission then the "Screen overlay detected" error shows up.

I believe this happen because the newer androids will not let you change the permissions of an app when the app is opened and thus you need to close it an allow to permissions in the Setting->App.

My question is how would you program the app to ask user the permission without getting into trouble with the screen overlay and thus making the UX horrible.

The problem is that once the users is prompted to DENY/ALLOW the location permission then after ALLOW is pressed the screen overlay message appears immediately.

Here is the code which handles the location:

public boolean requestCurrentLocation(float zoomLevel){
    if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
        mZoomLevel = zoomLevel;

        // Check if gps is enabled
        LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
        boolean gpsEnabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);
        if(!gpsEnabled){
            Log.d("GPS_TAG", "Gps not enabled");
            showToastMessageShort(getResources().getString(R.string.cannot_get_location));
            Intent gpsOptionsIntent = new Intent(
                    Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(gpsOptionsIntent);
            return false;
        }
        try{
            Log.d("GPS_TAG", "Calling FusedLocationApi request location updates");
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }catch(IllegalStateException ie){
            Log.d("GPS_TAG", "Error requesting FusedLocationApi locationUpdates: " + ie);
            return false;
        }
    }else{
        Log.d("GPS_TAG", "Location access not granted, asking for grant");
        showToastMessageShort(getResources().getString(R.string.cannot_get_location));
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, this.MY_PERMISSIONS_REQUEST_ACCESS_LOCATION);
        return false;
    }
    return true;
}

I also added the onRequestPermissionResult() method:

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_ACCESS_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.
                requestCurrentLocation(ZOOM_LEVEL_BUILDING);
            } else {
                Log.e("GPS_", "Cannot get gps location data, permission not granted!");
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
        // other 'case' lines to check for other
        // permissions this app might request
    }
}
KasparTr
  • 2,328
  • 5
  • 26
  • 55
  • post the whole code related to your current screen if you can plus permission model is same don't confuse yourself – Pavneet_Singh Sep 26 '16 at 11:09
  • The newer Android version will necessary ask for the permission in run time, so it's supposed to change the permission with the app open. You need to capture the permission result (with `onRequestPermissionsResult` )and try to do your action again. – Lucas Queiroz Ribeiro Sep 26 '16 at 11:27
  • The Overlay message is not necessary an error, if you already give a "no" answer to the permission request, for security Android M will ask you to change the permission in the settings, but some time it's kinda bug, there's a post in the [SO](http://android.stackexchange.com/questions/126798/screen-overlay-detected-dialog) explain the problem and suggesting a solution. – Lucas Queiroz Ribeiro Sep 26 '16 at 11:36

1 Answers1

2

You're going to hate this.
The problem is your call to "showToastMessageShort(...)".
You will see what you experienced if you Toast a message while a permissions request is pending.
To fix this, don't ever Toast in the code path of requesting permissions.

Yes, this is BS.

For more info: Screen overlay detected blocks Android permissions

Community
  • 1
  • 1
swooby
  • 3,005
  • 2
  • 36
  • 43