How to *correctly* ask for permissions?

Paula Perez :

I'm developing an Android app that requires 3 permissions on startup. I have to wait until the user to responds at the dialogs, if not, the app crashes as the permissions are mandatory.

What is the correct way to ask for those permissions? I wrote the below code, but the app freezes when responding the first permission (either rejecting or accepting).

Here is what I made:

    String[] perms = {"Manifest.permission.READ_PHONE_STATE", "Manifest.permission.ACCESS_COARSE_LOCATION","Manifest.permission.CALL_PHONE"};

    int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_PHONE_STATE);
    int result2 = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION);
    int result3 = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CALL_PHONE);

    if ((result1 == PackageManager.PERMISSION_GRANTED) && (result2 == PackageManager.PERMISSION_GRANTED) && (result3 == PackageManager.PERMISSION_GRANTED)) {
        onPermissionGranted();
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(perms, PERMISSION_REQUEST_CODE);
        } else {
            ActivityCompat.requestPermissions(this, perms, PERMISSION_REQUEST_CODE);
        }

    }

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case PERMISSION_REQUEST_CODE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                onPermissionGranted();
                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {
                Toast.makeText(MainActivity.this, R.string.permission_required, Toast.LENGTH_LONG).show();
                // permission denied, boo! Disable the
                // functionality that depends on this permission.


            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}
PPartisan :

There's no need to block, either with Thread#sleep or with while loops, as the permission request is asynchronous. Here's how your Activity should flow:

First, define the logic that requires permissions in order to run:

private void onPermissionGranted() {
   //code to execute
}

Then, in onCreate(), check to see whether you have those permissions. If you do, execute your code. If you don't, request the permission:

if (ContextCompat.checkSelfPermission(this,/*permissions*/) == PackageManager.PERMISSION_GRANTED) {
    onPermissionGranted();
} else {
   ActivityCompat.requestPermissions(this, /*permissions*/, /*request_code*/); 
}

When the permission status has updated, it calls through to onRequestPermissionsResult. If the permission was granted, then act on it here. Otherwise, do something else (either reshow the dialog or finish the activity).

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case /*our request code from before*/: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                onPermissionGranted();
            } else {
                Toast.makeText(this, "Permissions are required in order to run this app!", Toast.LENGTH_SHORT).show();
                finish();
            }
            return;
        }
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=115083&siteId=1