Android Tutorial

Software Setup and Configuration

Android Studio

File Structure

Components

Core Topics

Layout

View

Button

Intent and Intent Filters

Toast

RecyclerView

Fragments

Adapters

Other UI Component

Image Loading Libraries

Date and Time

Material Design

Bars

Working with Google Maps

Chart

Animation

Database

Advance Android

Jetpack

Architecture

App Publish

App Monetization

Easy Runtime Permissions in Android with Dexter

The process of asking for runtime permissions in Android can be tedious, especially when dealing with multiple permissions and handling all the possible user interactions. Dexter is a library that simplifies the process of requesting permissions at runtime.

Below are the steps to use the Dexter library for runtime permissions:

  • Add the Dependency

First, add the Dexter dependency to your build.gradle (Module: app):

implementation 'com.karumi:dexter:6.2.3' // Check for the latest version on the repository
  • Request a Single Permission

To request a single permission, you can use the following code:

Dexter.withContext(this)
    .withPermission(Manifest.permission.CAMERA)
    .withListener(object : PermissionListener {
        override fun onPermissionGranted(response: PermissionGrantedResponse) {
            // Permission granted. Do your task.
        }

        override fun onPermissionDenied(response: PermissionDeniedResponse) {
            // Permission denied.
        }

        override fun onPermissionRationaleShouldBeShown(permission: PermissionRequest, token: PermissionToken) {
            // User denied permission with "Don't ask again". Display a rationale.
            token.continuePermissionRequest()
        }
    }).check()
  • Request Multiple Permissions

If you need to ask for multiple permissions simultaneously:

Dexter.withContext(this)
    .withPermissions(
        Manifest.permission.CAMERA,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
    .withListener(object : MultiplePermissionsListener {
        override fun onPermissionsChecked(report: MultiplePermissionsReport) {
            if (report.areAllPermissionsGranted()) {
                // Do your task.
            }

            if (report.isAnyPermissionPermanentlyDenied) {
                // Handle the situation where some permissions are denied forever.
            }
        }

        override fun onPermissionRationaleShouldBeShown(permissions: List<PermissionRequest>, token: PermissionToken) {
            token.continuePermissionRequest()
        }
    }).check()
  • Handle "Never Ask Again"

For situations where the user selects "Never Ask Again" for a permission, you may want to navigate the user to the app settings. You can use the following code snippet inside the onPermissionRationaleShouldBeShown or onPermissionDenied methods:

val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", packageName, null)
intent.data = uri
startActivity(intent)

Dexter makes it easy to request permissions and handle various scenarios. Always ensure you're handling all possible cases, including when a user denies a permission or selects "Never Ask Again", to ensure the best user experience.

  1. Implementing Easy Runtime Permissions with Dexter in Android:

    • Description: Dexter is a third-party library that simplifies the process of handling runtime permissions in Android. It provides an easy and concise API for requesting and handling permissions.
    • Code:
      // Add Dexter dependency in your app/build.gradle
      implementation 'com.karumi:dexter:6.2.2'
      
      // Requesting a single permission
      Dexter.withContext(this)
          .withPermission(Manifest.permission.CAMERA)
          .withListener(object : PermissionListener {
              override fun onPermissionGranted(response: PermissionGrantedResponse) {
                  // Permission granted, handle the task
              }
      
              override fun onPermissionDenied(response: PermissionDeniedResponse) {
                  // Permission denied
              }
      
              override fun onPermissionRationaleShouldBeShown(
                  permission: PermissionRequest?,
                  token: PermissionToken?
              ) {
                  // Show rationale for permission
                  token?.continuePermissionRequest()
              }
          }).check()
      
  2. Dexter Library Example Code for Android Permissions:

    • Description: Provides a simple example of using Dexter library to request a single permission.
    • Code:
      Dexter.withContext(this)
          .withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
          .withListener(object : PermissionListener {
              // Implementation of onPermissionGranted, onPermissionDenied, onPermissionRationaleShouldBeShown
          }).check()
      
  3. Handling Multiple Permissions with Dexter in Android:

    • Description: Demonstrates how to request multiple permissions using Dexter.
    • Code:
      Dexter.withContext(this)
          .withPermissions(
              Manifest.permission.CAMERA,
              Manifest.permission.WRITE_EXTERNAL_STORAGE
          )
          .withListener(object : MultiplePermissionsListener {
              // Implementation of onPermissionsChecked, onPermissionRationaleShouldBeShown
          }).check()
      
  4. Customizing Dexter Library for Runtime Permissions:

    • Description: Shows how to customize Dexter for runtime permissions with specific options.
    • Code:
      Dexter.withContext(this)
          .withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
          .withListener(object : PermissionListener {
              // Implementation of onPermissionGranted, onPermissionDenied, onPermissionRationaleShouldBeShown
          })
          .withErrorListener { error ->
              // Handle errors in permission handling
          }
          .onSameThread() // Execute listener callbacks on the same thread
          .check()
      
  5. Using Dexter for Simple Permission Requests in Android:

    • Description: Provides a concise example of using Dexter for a simple permission request.
    • Code:
      Dexter.withContext(this)
          .withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
          .withListener(object : PermissionListener {
              // Implementation of onPermissionGranted, onPermissionDenied, onPermissionRationaleShouldBeShown
          }).check()
      
  6. Runtime Permission Callbacks with Dexter in Kotlin:

    • Description: Demonstrates how to handle runtime permission callbacks using Dexter in Kotlin.
    • Code:
      Dexter.withContext(this)
          .withPermission(Manifest.permission.READ_CONTACTS)
          .withListener(object : PermissionListener {
              override fun onPermissionGranted(response: PermissionGrantedResponse) {
                  // Permission granted, handle the task
              }
      
              override fun onPermissionDenied(response: PermissionDeniedResponse) {
                  // Permission denied
              }
      
              override fun onPermissionRationaleShouldBeShown(
                  permission: PermissionRequest?,
                  token: PermissionToken?
              ) {
                  // Show rationale for permission
                  token?.continuePermissionRequest()
              }
          }).check()
      
  7. Handling Rationale for Permissions Using Dexter in Android:

    • Description: Shows how to handle rationale for permissions using Dexter library in Android.
    • Code:
      Dexter.withContext(this)
          .withPermission(Manifest.permission.CAMERA)
          .withListener(object : PermissionListener {
              override fun onPermissionGranted(response: PermissionGrantedResponse) {
                  // Permission granted, handle the task
              }
      
              override fun onPermissionDenied(response: PermissionDeniedResponse) {
                  // Permission denied, show rationale
                  if (response.isPermanentlyDenied) {
                      // Show a dialog explaining the need for the permission
                      // and redirect user to app settings
                  } else {
                      // Show a dialog explaining the need for the permission
                  }
              }
      
              override fun onPermissionRationaleShouldBeShown(
                  permission: PermissionRequest?,
                  token: PermissionToken?
              ) {
                  // Show rationale for permission
                  token?.continuePermissionRequest()
              }
          }).check()