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");
}
}
}
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");
}
}
}