Signup/Sign In

Permissions in Android

While using some apps, have you ever encountered with the following images?

These are known as Android runtime permissions.


Android is an operating system, in which each app runs with a distinct system identity (Linux user ID and group ID). Similarly, other parts of the system are also separated into distinct identities. Linux thereby isolates apps from each other and from the system.

Therefore, when apps needs to request access to other resources and data, they do it by declaring the permissions they need. Depending on how sensitive the area is, the system may grant the permission automatically, or may prompt the user to approve or reject the request.


Normal and Dangerous Permissions

System permissions are divided into two important protection levels - Normal Persmissions and Dangerous Permissions

Normal permissions cover areas where your app needs to access outside data or resources, but provided there's very little risk to the user's privacy or the operation of other apps. For example, permission to set the time zone is a normal permission. If an app declares that it needs a normal permission, the system automatically grants the permission to the app.

Dangerous permissions cover areas where the app wants outside data or resources that involve the user's private information, or could potentially affect the user's stored data or the operation of other apps. For example, the ability to read the user's contacts is a dangerous permission. If an app declares that it needs a dangerous permission, the user has to explicitly grant the permission to the app.

Beginning in Android 6.0(API level 23), the effect of permission declaration is different depending on the system version and your app's target SDK level:

  • If the device is running Android 5.1 or lower, or your app's target SDK is 22 or lower

    If you list a dangerous permission in your manifest, the user has to grant the permission when they install the app; if they do not grant the permission, the system does not install the app at all.

  • If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher

    The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.


Check for Permissions

If your app needs a dangerous permission, you must check whether you have that permission or not. To check if you have a permission, call the ContextCompat.checkSelfPermission() method. For example, following snippet shows how to check if the activity has permission to write to the calendar:

//Assume thisActivity is the current activity

int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.WRITE_CALENDAR);

If the app has the permission, the method returns PackageManager.PERMISSION_GRANTED, and the app can proceed with the operation. If the app does not have the permission, the method returns PERMISSION_DENIED, and the app has to explicitly ask the user for permission.


Request Permissions

If your app needs a dangerous permission that was listed in the app manifest file, it must ask the user to grant the permission. Android provides several methods you can use to request a permission. Calling these methods brings up a standard Android dialog, which you cannot customize.

If your app doesn't already have the permission it needs, the app must call one of the requestPermissions() methods to request the appropriate permissions. Your app passes the permissions it wants, and also an integer request code that you specify to identify this permission request. This method functions asynchronously: it returns right away, and after the user responds to the dialog box, the system calls the app's callback method with the results, passing the same request code that the app passed to requestPermissions().

The following code checks if the app has permission to read the user's contacts, and requests the permission if necessary:

//Here, thisActivity is the current activity

if (ContextCompat.checkSelfPermission(thisActivity,

                Manifest.permission.READ_CONTACTS)

        != PackageManager.PERMISSION_GRANTED) {

        ActivityCompat.requestPermissions(thisActivity,

                new String[]{Manifest.permission.READ_CONTACTS},

                MY_PERMISSIONS_REQUEST_READ_CONTACTS);



        //MY_PERMISSIONS_REQUEST_READ_CONTACTS is a defined int constant. The callback method gets the result of the request.

    }

}

Note: When your app calls requestPermissions(), the system shows a standard dialog box to the user. Your app cannot configure or alter that dialog box. If you need to provide any information or explanation to the user, you should do that before you call requestPermissions().


Handle the Permissions Request Response

When your app requests permissions, the system presents a dialog box to the user. When the user responds, the system invokes your app's onRequestPermissionsResult() method, passing it the user response. Your app has to override that method to find out whether the permission was granted. The callback passes the same request code you passed to requestPermissions(). For example, if an app requests READ_CONTACTS access it might have the following callback method:

@Override

public void onRequestPermissionsResult(int requestCode,

        String permissions[], int[] grantResults) {

    switch (requestCode) {

        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {

            // 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.

            } else {

                //Permission denied, boo! Disable the functionality that depends on this permission.

            }

            return;

        }

        //Other 'case' lines to check for other permissions this app might request

    }

}

The dialog box shown by the system describes the permission group your app needs access to; it does not list the specific permission. For example, if you request the READ_CONTACTS permission, the system dialog box just says your app needs access to the device's contacts. The user only needs to grant permission once for each permission group.

For example, suppose you list both READ_CONTACTS and WRITE_CONTACTS in your app manifest. If you request READ_CONTACTS and the user grants the permission, and you then request WRITE_CONTACTS, the system immediately grants you that permission without interacting with the user.

Note: Your app still needs to explicitly request every permission it needs, even if the user has already granted another permission in the same group. In addition, the grouping of permissions into groups may change in future Android releases. Your code should not rely on the assumption that particular permissions are or are not in the same group.

When the system asks the user to grant a permission, the user has the option of telling the system not to ask for that permission again, by clicking on "Don't ask again" checkbox. In that case, any time an app uses requestPermissions() to ask for that permission again, the system immediately denies the request. This means that when you call requestPermissions(), you cannot assume that any direct interaction with the user has taken place.