How to Fix Android Permission Denied (Runtime Permission) Error
In this tutorial, you'll learn about How to Fix Android Permission Denied (Runtime Permission) Error. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.
The Problem
Your app crashes or silently fails when accessing a feature:
java.lang.SecurityException: Permission Denial:
reading com.android.providers.contacts.ContactsProvider
requires android.permission.READ_CONTACTS
Or the API returns no data without an error message because the permission was denied.
Quick Fix
Step 1: Declare the permission in AndroidManifest.xml
<manifest ...>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
<uses-permission> declares the permission to the system. For dangerous permissions (camera, location, contacts, etc.), runtime request is also required.
Step 2: Request permission at runtime (API 23+)
private val CAMERA_PERMISSION_CODE = 100
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA),
CAMERA_PERMISSION_CODE
)
} else {
openCamera()
}
Step 3: Handle the permission result
override fun onRequestPermissionsResult(
requestCode: Int, permissions: Array<String>, grantResults: IntArray
) {
when (requestCode) {
CAMERA_PERMISSION_CODE -> {
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openCamera()
} else {
// Show rationale and guide user to Settings
}
}
}
}
Step 4: Handle permanently denied permission
If the user checked "Never ask again," shouldShowRequestPermissionRationale returns false:
if (!shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
// Navigate user to app settings
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", packageName, null)
}
startActivity(intent)
}
Step 5: Check for permission on Android 13+
Android 13 introduces granular photo and notification permissions:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
Replace READ_EXTERNAL_STORAGE with READ_MEDIA_IMAGES for API 33+.
Step 6: Test with permission off
On emulator or device:
Settings > Apps > Your App > Permissions > Toggle off
Verify the app degrades gracefully instead of crashing.
Prevention
- Request permissions only when the feature is accessed, not at app launch.
- Show a rationale dialog before requesting sensitive permissions.
- Handle the "never ask again" case with a Settings deep link.
Common Mistakes with permission denied
- Using
returnto exit a function early instead of wrapping a pure value in the monad - Mixing let bindings with <- bindings in do notation, producing type errors
- Overlapping type class instances that cause GHC to reject the program with ambiguous dispatch errors
These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
DodaTech Tool Reference
Durga Antivirus Pro analyzes permission usage across installed apps and flags over-permissioned applications. Use Doda Browser's Privacy Dashboard to audit which permissions your app requests at runtime.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro