Runtime Permissions in Android app

Hey Technoz, hope you are doing well. In android, we usually need the permissions to perform some of the tasks. We need to list these permissions in our manifest file. However, from android 6.0 Marshmallow, we have to explicitly ask the user for permissions at runtime, as they are not given by default. So in this tutorial, we will see how to ask user for the permissions at runtime.

Understanding permissions

As you are here, probably you know what are permissions in android. However, android has divided the runtime permissions in two types namely normal permissions and dangerous permissions.  Normal permissions are the ones which does not deal with user’s personal data, while dangerous permissions are the ones which requires access to user’s sensitive data like read/write access of data, send sms, etc. The android OS grants the normal permissions the first time user install the app, while the dangerous permissions require to ask user explicitly, that’s what we are going to learn in this tutorial.

Declaring Permissions

First of all, start a new android studio project or if you wish, you can continue with your existing one. In this tutorial, we are asking the runtime permissions in android app – specifically the storage permission. So, open the AndroidManifest.xml and declare the following storage permission in it.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Now, come to your layout file in my case, activity_main.xml. we are simply putting simple Textviews and a Button to request permissions.  Lets put the following code in it.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_margin="8sp">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Technopoints"
        android:textSize="25sp"
        android:gravity="center_horizontal"/>
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Runtime Permissions in android app tutorial"
        android:textSize="18sp"
        android:gravity="center_horizontal"
        android:layout_marginTop="8sp"/>
    <Button
        android:id="@+id/permissions"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Check Permissions"
        android:layout_marginTop="8sp"/>
</LinearLayout>

As you can see above code, the layout is quite simple.

Building Logic for runtime permissions in android app

Lets move towards the MainActivity.java file where we will implement all the intended logic.

package net.softglobe.myapplication;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;

public class MainActivity extends AppCompatActivity {
    private static final int PERMISSION_REQUEST_CODE = 200;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button permissions = findViewById(R.id.permissions);
        permissions.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (checkPermission())
                    Toast.makeText(MainActivity.this, "Permissions Already Granted", Toast.LENGTH_SHORT).show();
                else
                    requestPermission();
            }
        });
    }

    //method to check app permissions
    private boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(getApplicationContext(), WRITE_EXTERNAL_STORAGE);
        return result == PackageManager.PERMISSION_GRANTED;
    }

    //method to request permissions from user
    private void requestPermission() {
        ActivityCompat.requestPermissions(this, new String[]{WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
    }

    //called automatically after asking permissions to show the result whether allowed or denied
    @Override
    public void onRequestPermissionsResult(int requestCode, final String permissions[], int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0) {
                boolean storageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                if (storageAccepted)
                    Toast.makeText(this, "Permissions granted", Toast.LENGTH_SHORT).show();
                else {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        if (shouldShowRequestPermissionRationale(permissions[0])) {
                            showMessageOKCancel("Please allow required permissions", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    requestPermissions(permissions, PERMISSION_REQUEST_CODE);
                                }
                            });
                            return;
                        }
                    } else {
                        Toast.makeText(this, "Please allow required permissions", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }
    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(MainActivity.this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null)
                .create()
                .show();
    }
}

In the above file, at top, we have declared the static integer for the PERMISSION_REQUEST_CODE, which is same throughout the app for convenience. You can assign any value to it. Later, we are simply referring the button in layout and handling the onclick event so that it should call the method checkPermission(). We have some methods in above file, let me explain them one by one what they do in a task of getting runtime permissions in android app.

    • checkPermission(): This is a boolean method which checks whether the permissions are already granted or not and returns the relevant result. The checkSelfPermission() method is used to check for the permissions which takes two arguments as application context and second one is a permission. Note that, if you require user to grant more than one permission, then you have to apply this method for each permission individually.
    • requestPermission(): This method performs the task of getting permissions from the user by showing the appropriate message to user. You do not need to design the UI for asking permissions, android does that for you. This method takes  arguments as context, a string array of permissions, and the permission request code respectively. You can declare more than one permissions the the string array here. However, the PERMISSION_REQUEST_CODE remains the same.
    • onRequestPermissionsResult(): This method overrides from the superclass, and is called automatically after the requestPermission() call to know the result of permissions. This method accepts three parameters as request code, array of permissions and an array of results of respective permissions. We are checking if the user has granted the permissions. If yes, then we will show a Toast confirmation message and if not granted, then we are building an AlertDialog requesting to grant the permissions.

See the Results

Once the user grants permissions, then you can use that feature anytime in future. Android grouped the permissions together in such a way that similar tasks do not need permissions again and again. For ex. Once user grants the storage permission, then the app can read, write and modify contents in storage regardless of asking separately for reading, writing and modifying permissions.

Please note that the user can revoke the permission anytime for the app. So, it is good practice to always check for the runtime permissions in android app when performing the task that requires dangerous permissions.

That’s it! this simple code will do our intended work. Lets see the below screenshot of how the permission will be asked.

Runtime permissions in android

If you want to jump directly on the implementation, then feel free to download the source code from the below link.

Download Source Code

Hope you liked this simple and useful tutorial. If you have any queries or difficulties implementing this tutorial, then please let me know in the comment box below. I will try my best to answer you. If you find this tutorial useful, then please do share it with your friends and subscribe to our email newsletter to get notified about such useful tutorials in your inbox. Happy Coding. 🙂

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.