Declaring and Handling Permissions Since Android API 23 Tutorial

Udemy Generic 728x90

Objective

In this tutorial we will learn the process of declaring the permissions and handle user response through a demo android app.

 

Download Source Code download
Video Demo

 

Every Android app has limited scope and if it wants to access resources outside of its scope, then it has to request appropriate permissions. We declare those permissions in the manifest file of the app. Earlier all permissions mentioned in the Manifest were granted during the installation of the app, but it was not the best of methods. Users of the app did not know the purpose of the most permissions or where they will be used within the app.

With the release of Android Marshmallow, Android is more focused on users privacy & security and hence, giving user more control over the app. Now, depending on the sensitivity of the permission the system might grant the permission itself, or the device user might have to explicitly grant/accept permission request. Earlier versions of Android will keep granting the permissions during the installation of the app.

 

Step 2

Prerequisites

  • Android API 23 and above

 

Step 3

Declare Permissions in Manifest File

First, you have to add the permissions to your manifest file. To do so, you should determine what features you are going to implement in your application and note down the permissions related to those features. Typically, an app need permissions whenever it uses user information or resources that app doesn’t create, or performs any action that affects the behavior of the device or any other app.
To declare the permission needed by your app, use tag in you manifest file. Here is the sample code snippet for the same :

<br />
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;<br />
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;<br />
    package=&quot;com.numetriclabz.newpermissions&quot;&gt;</p>
<p>    &lt;uses-permission android:name=&quot;android.permission.INTERNET&quot;/&gt;<br />
    &lt;uses-permission android:name=&quot;android.permission.READ_CONTACTS&quot;/&gt;</p>
<p>    &lt;application ...&gt;<br />
        ...<br />
    &lt;/application&gt;<br />
&lt;/manifest&gt;<br />

 

Step 4

Types of Permissions

System permissions are divided into two groups :

  • Normal Permissions : they don’t directly affect the user’s privacy. For example, if your app wants permission to use Bluetooth of device then system will automatically grant the permission at the time of app installation.
  • Dangerous Permissions : these permissions provides app access to confidential data of the user. If you have declared any dangerous permission in your app then the user has to explicitly approve that permission during the execution of specific process that needs access to the user’s data.

For more information on Normal or Dangerous permissions, check out this link .

 

Step 5

Check For  Permissions

If you have declared a dangerous permission in your manifest, then you must check whether your app have that permission every time your app execute process which requires that permission. Since a user can revoke the permission any time from settings you can not assume that your app has the permission now even if your app have that permission yesterday.

To check whether your app has the permission, call the ContextCompat.checkSelfPermission() method.  If app has the permission, then method returns PackageManager.PERMISSION_GRANTED and if not then returns PERMISSION_DENIED. If permission is already granted, then app proceeds further otherwise you have to explicitly ask for the permission.

Here is the code snippet to check if app has permission to read contacts :

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivityManifest.permission.READ_CONTACTS);

 

Step 6

Request and Handle Permissions

Requesting permissions is a tricky process as you might need to explain the user that why your app need the permission and handle the user response efficiently. The user may grant or deny the permission and in case of denial, you need to make sure that your app does not breakdown. You can request a permission using several methods provided by Android. Use of those methods will open a standard dialog box that you will not be able to customize.

 

Step 6.1

Explain the Permission

To make sure that user grants access to the required permission, you should explain the purpose of the required permission. This will help the user to understand why you need the permission. For example, if a user uses a chat application, then he won’t be surprised if app asks for READ_CONTACTS permission, but the user might get confused if app asks for LOCATION permission. So, before requesting a permission you should provide an explanation to the user for the same. The explanation should be simple and precise as too much detail may overwhelm the user and user may find the app confusing and frustrating.

One approach to provide explanation will be the scenario where the user has already declined the permission request. Suppose, a user wants to use the particular functionality which needs a permission, but user keeps declining the request, then its a good time to explain the user as why app needs the permission to provide the functionality.

Android has provided a utility method shouldShowRequestPermissionRationale(), to help developers to find situations where the user might need an explanation. This method returns true if the app has requested the same permission and got declined by the user previously.

Note : This method will return false if user has declined the permission and chose DO NOT ASK AGAIN option in permission request dialog. 
This method also returns false if device policy prohibits app from having that permission.

 

screen_1

Step 6.2

Request the Permission

To request the appropriate permission you need to implement the requestPermissions() method. Within the method, you need to pass the permissions and a request code to identify the permission request. After the response of the user through dialog box, the system calls the callback method of the app with the result and passes the same request code that was passed to requestPermission() method.

Here is the code snippet to check if app already has the permission and request the permission if needed :

</p>
<p>if (ContextCompat.checkSelfPermission(this,<br />
                             Manifest.permission.READ_CONTACTS)<br />
                             != PackageManager.PERMISSION_GRANTED) {</p>
<p>    // Already declined the permission<br />
    if (ActivityCompat.shouldShowRequestPermissionRationale(this,<br />
                                    Manifest.permission.READ_CONTACTS)) {</p>
<p>        // Show an expanation to the user *asynchronously* -- don't block<br />
        // this thread waiting for the user's response! After the user<br />
        // sees the explanation, try again to request the permission.<br />
    } <br />
    else {</p>
<p>        // No explanation for the first time<br />
        ActivityCompat.requestPermissions(this,<br />
                       new String[]{Manifest.permission.READ_CONTACTS},<br />
                       REQUEST_CONTACTS);</p>
<p>        // REQUEST_CONTACTS is an<br />
        // app-defined int constant. The callback method gets the<br />
        // result of the request.<br />
    }<br />
}</p>
<p>

 

screen_1

Step 6.3

Handle the Permission

After the response from the user, the system passes the user response to your app using onRequestPermissionsResult() method. This callback will have the same request code passed to requestPermissions() method.  You need to override onRequestPermissionsResult() method to check whether the permission is granted or not.

Here is the code snippet to handle the request response :

</p>
<p>@Override<br />
if (requestCode == REQUEST_CONTACTS) {</p>
<p>    Log.i(TAG, &quot;Received response for contact permissions request.&quot;);<br />
    // We have requested multiple permissions for contacts, so all of them need to be<br />
    // checked.</p>
<p>    if (PermissionUtil.verifyPermissions(grantResults)) {<br />
        // All required permissions have been granted, display contacts fragment.<br />
    }<br />
    else {</p>
<p>        Log.i(TAG, &quot;Contacts permissions were NOT granted.&quot;);<br />
        Snackbar.make(coordinatorLayout,&quot;Permissions not granted&quot;,<br />
                             Snackbar.LENGTH_SHORT).show();<br />
    }<br />
}<br />
else {<br />
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);<br />
}<br />

 

screen_1
 

screen_1

The dialog box invoked by the system during the permission request describes the specific group to which permission belongs. It does not list the specific permission.
For ex, if your app requests for the READ_CONTACTS permission, then the dialog box just says that the app needs to access the device contacts. It will not describe that whether it needs write access or read access. Also, once the permission for a group is granted, then system will automatically grant access to all the permissions of that group.

So, when READ_CONTACTS permission is granted and you request the WRITE_CONTACTS permission of same group, then the system will call onRequestPermissionsResult() callback method and grant the permission by automatically passing the PERMISSION_GRANTED, same way if a user had explicitly granted the permission through a dialog box.

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.

 

Download Source Code download
 

Udemy Generic 728x90

Spread the word. Share this post!

  • Rakhi Dhavale

    Clean example ! Thanks !

    • Udit Singh

      Glad it helped