Android Easy Runtime Permissions with Dexter

4th FEB 2019

android



Welcome folks I am back with another blog post. In this post we will be implementing Android Marshmallow Runtime Permissions using an Android library called as Dexter. Dexter allows you to to implement these runtime permissions with ease. Whenever user wants to initiate some action it will ask the user the appropriate permission at runtime. Let’s implement this and get started with the post.





This is a introductory post to the library Dexter. I would like to tell this library handles lots of other features as well including snackbar, error handling. You can read more about it in the Dexter Developers Page.




To get started with the library you need to include it in the build.gradle file. Just add the following lines of code given below.




dependencies {
    // Dexter runtime permissions
    implementation 'com.karumi:dexter:4.2.0'
}



REQUESTING SINGLE PERMISSION USING DEXTER




Now to request Single Permission using the Dexter Library you need to use withPermission() and also this method takes the required permission to pass. We will also need a callback listener in the form of PermissionCallback to get the state of the permission. This callback has two methods namely which are as follows: 1) onPermissionGranted() -> It will be called whenever the permission has been granted by the user. 2) onPermissionDenied() -> This method will be called whenever the permission has been denied by the user. If the user has permanently denied the permission then you can also check this by using the response.isPermanentlyDenied() condition. The below code is given for the camera permission. So after executing this code user will granted with the camera permission. First of all just make sure you include the camera permission in the manifest file like this:




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



After including the permission in the manifest file. Just copy paste this code in layout file.




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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAlignment="center"
        android:text="Requesting Single Permission (Camera Permission)"
        android:textSize="22sp"
        android:textStyle="bold"/>

    <Button
        android:layout_marginTop="50dp"
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Camera" />


</LinearLayout>






After making the layout of this permission. We need to write Java code to implement the runtime permission using Dexter. Just copy paste this code in activity_main.java file




package com.codingshiksha.androidcaptcha;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;


public class MainActivity extends Activity implements View.OnClickListener {

    Button btn;

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.btn);

        btn.setOnClickListener(this);

    }
    @Override
    public void onClick(View view) {
        requestPermissions();
    }

    private void requestPermissions(){
        Dexter.withActivity(this)

                .withPermission(Manifest.permission.CAMERA)

                .withListener(new PermissionListener() {

                    @Override

                    public void onPermissionGranted(PermissionGrantedResponse response) {

                        // the user has granted the permission so you can open the camera

                        openCamera();

                    }

                    @Override

                    public void onPermissionDenied(PermissionDeniedResponse response) {


                        if (response.isPermanentlyDenied()) {

                            // here user permanently denied the permission so you can close the app

                        closeApp();

                        }

                    }

                    @Override

                    public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {

                        token.continuePermissionRequest();

                    }

                }).check();
    }

    private void openCamera(){
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        startActivity(intent);

    }

    private void closeApp(){
        finish();
        System.exit(0);
    }

}









As you can see when the app launches and the user clicks the camera button it first of all asks the user dynamically at runtime that it requires the camera permission before performing the actual operation. If I allow the permission then only the camera application opened. But in the scenario if I deny the permission permanently then it will close the application. This is my implementation in the scenario when the user rejects the permission.




REQUESTING MULTIPLE PERMISSIONS USING DEXTER




Similarly we can also request multiple permissions using Dexter. For this purpose the process will remain the same. First of all include the necessary permissions in the manifest file. In this case I am taking read_external_storage, write_internal_storge and Internet Permission.




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



Similarly we can also request multiple permissions using Dexter. For this purpose the process will remain the same. First of all include the necessary permissions in the manifest file. In this case I am taking read_external_storage, write_internal_storge and Internet Permission.




After including the permission in the manifest file. Just copy paste this code in layout file.






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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAlignment="center"
        android:text="Requesting Multiple Permissions"
        android:textSize="22sp"
        android:textStyle="bold"/>

    <Button
        android:layout_marginTop="50dp"
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Multiple" />


</LinearLayout>






After making the layout of the permission we will making the logic in the java file. So just copy paste the code given below.




package com.codingshiksha.androidcaptcha;

import android.Manifest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.karumi.dexter.Dexter;
import com.karumi.dexter.MultiplePermissionsReport;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.multi.MultiplePermissionsListener;

import java.util.List;


public class MainActivity extends Activity implements View.OnClickListener {

    Button btn;

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        btn = (Button) findViewById(R.id.btn);

        btn.setOnClickListener(this);

    }
    @Override
    public void onClick(View view) {
        requestPermissions();
    }

    private void requestPermissions(){
        Dexter.withActivity(this)
                .withPermissions(
                        Manifest.permission.READ_EXTERNAL_STORAGE,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.INTERNET
                ).withListener(new MultiplePermissionsListener() {
            @Override public void onPermissionsChecked(MultiplePermissionsReport report) {openMultipleThings();}
            @Override public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {}
        }).check();
    }

    private void openMultipleThings(){
        Toast.makeText(this,"You can implement action",Toast.LENGTH_LONG).show();

    }

}






Congratulations we are done implementing runtime permissions using Dexter. Thanks for reading the post and if you want to receive more tutorials like this please subscribe to the newsletter.





About Author

Gautam Sharma

Developer, Tech. Evangalist.