Search code examples
javaandroidandroid-permissions

Android permission getting rejected when asking for multiple permissions


I need to ask the user for GPS and filesystem permissions in two separate requests.

Expected behaviour: The app shows request for GPS permissions, and after user makes their decision, app will show filesystem permission request and let user decide again.

Actual behaviour: Only request for GPS permission is shown, and filesystem permissions are automatically rejected without showing any dialog.

Target Android version: 5.0 and higher (API 21+)

Could someone please tell me how to fix this? Thank you in advance!

My code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...

    checkLocationPermissions();
    checkLoggingPermissions();

    ...
    ...
}

private void checkLoggingPermissions() {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if(checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            Log.i(TAG, "Requesting filesystem permissions from user");

            ActivityCompat.requestPermissions(this, new String[]
                    {Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    FrontendConstants.PERMISSION_FILESYSTEM_REQUEST_CODE);
        }
        else {
            LoggingService.init();
        }
    }
    else {
        LoggingService.init();
    }
}

private void checkLocationPermissions() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
                this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            Log.i(TAG, "Requesting GPS permissions from user");

            ActivityCompat.requestPermissions(this, new String[] {
                    Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.INTERNET
            }, FrontendConstants.PERMISSION_GPS_REQUEST_CODE);
        }
        else {
            locationService = LocationService.getInstance(this);
        }
    }
    else {
        locationService = LocationService.getInstance(this);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                   String permissions[], int[] grantResults) {
    if(FrontendConstants.PERMISSION_GPS_REQUEST_CODE == requestCode) {
        if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.e(TAG, "+++ User accepted GPS permission request");
            locationService = LocationService.getInstance(this);
        }
        else {
            Log.e(TAG, "--- User rejected GPS permission request");
        }
    }

    if(FrontendConstants.PERMISSION_FILESYSTEM_REQUEST_CODE == requestCode) {
        if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Log.e(TAG, "+++ User accepted filesystem permission request");
            LoggingService.init();
        }
        else {
            Log.e(TAG, "--- User rejected filesystem permission request");
        }
    }
}

Solution

  • So I have solved the problem using your advices. My approach is now to ask for all permissions in one request, and then analyze the results in onRequestPermissionsResult.

    To do that, I have created PermissionsHelper class:

    import android.content.pm.PackageManager;
    
    public class PermissionsHelper {
        private String[] permissions;
        private int[] grantResults;
    
        public PermissionsHelper(String[] permissions, int[] grantResults) {
            this.permissions = permissions;
            this.grantResults = grantResults;
        }
    
        public boolean isPermissionGranted(String permission) {
            final int length = permissions.length;
    
            for(int i = 0; i < length; i++) {
                if(permissions[i].equals(permission)) {
                    return grantResults[i] == PackageManager.PERMISSION_GRANTED;
                }
            }
    
            // if permission wasn't found, we weren't even asking for it, so we consider it
            // as granted
            return true;
        }
    
        public boolean arePermissionsGranted(String ... permissions) {
            for(String permission : permissions) {
                if(!isPermissionGranted(permission)) return false;
            }
    
            return true;
        }
    }
    

    Then I do this in my Activity, and it seems to work perfectly:

    private void requestPermissions() {
        requestPermissions(new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION
        });
    }
    
    private void requestPermissions(String[] permissions) {
        List<String> notGranted = new ArrayList<>();
    
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            for(String permission : permissions) {
                if(checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                    notGranted.add(permission);
                }
            }
    
            if(!notGranted.isEmpty()) {
                ActivityCompat.requestPermissions(this, notGranted.toArray(new String[0]),
                        FrontendConstants.PERMISSION_REQUEST_CODE);
            }
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        if(FrontendConstants.PERMISSION_REQUEST_CODE == requestCode) {
            PermissionsHelper helper = new PermissionsHelper(permissions, grantResults);
    
            if(helper.isPermissionGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                Log.i(TAG, "+++ User accepted filesystem permission request");
            }
            else {
                Log.e(TAG, "--- User rejected filesystem permission request");
            }
    
            if(helper.arePermissionsGranted(Manifest.permission.ACCESS_FINE_LOCATION,
                    Manifest.permission.ACCESS_COARSE_LOCATION)) {
                Log.i(TAG, "+++ User accepted GPS permission request");
            }
            else {
                Log.e(TAG, "--- User rejected GPS permission request");
            }
        }
    }