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
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:
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
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()
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()
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.
Implementing Easy Runtime Permissions with Dexter in Android:
// 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()
Dexter Library Example Code for Android Permissions:
Dexter.withContext(this) .withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) .withListener(object : PermissionListener { // Implementation of onPermissionGranted, onPermissionDenied, onPermissionRationaleShouldBeShown }).check()
Handling Multiple Permissions with Dexter in Android:
Dexter.withContext(this) .withPermissions( Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE ) .withListener(object : MultiplePermissionsListener { // Implementation of onPermissionsChecked, onPermissionRationaleShouldBeShown }).check()
Customizing Dexter Library for Runtime Permissions:
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()
Using Dexter for Simple Permission Requests in Android:
Dexter.withContext(this) .withPermission(Manifest.permission.ACCESS_FINE_LOCATION) .withListener(object : PermissionListener { // Implementation of onPermissionGranted, onPermissionDenied, onPermissionRationaleShouldBeShown }).check()
Runtime Permission Callbacks with Dexter in Kotlin:
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()
Handling Rationale for Permissions Using Dexter in Android:
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()