Permissions cheat sheet
All 43 dangerous permissions with the API level each was introduced at, generated from the official reference.
The dangerous permissions are the ones that show a dialog. There are 43 of them, and knowing which API level each arrived at tells you what you need to guard.
TL;DR#
- Dangerous permissions need the user's consent. Everything else is granted at install.
- The list has grown mostly in two waves: runtime permissions in Android 6.0, and granular media and nearby-devices permissions in Android 12 and 13.
READ_EXTERNAL_STORAGEstill exists but does nothing for media on Android 13+.
Mental model#
A permission is a capability, and the protection level says who can be trusted with it without
asking. normal is trusted, dangerous is not, signature is only for apps signed with the
definer's key.
Where the analogy breaks#
The protection level is not the whole story. AppOps can block an operation even when the permission is granted, and the permission group determines which dialog the user sees, not what is granted.
The big picture#
Text description of this diagram
A treemap of the software on an Android phone. The permissions sheet maps onto the app and framework layers: permissions are declared by apps and enforced by framework services, which is why the list of dangerous permissions reflects what the framework mediates access to.
Deep dive#
| Permission | Added at API | Deprecated at API |
|---|---|---|
ACCESS_COARSE_LOCATION | 1 | — |
ACCESS_FINE_LOCATION | 1 | — |
CALL_PHONE | 1 | — |
CAMERA | 1 | — |
GET_ACCOUNTS | 1 | — |
PROCESS_OUTGOING_CALLS | 1 | — |
READ_CALENDAR | 1 | — |
READ_CONTACTS | 1 | — |
READ_PHONE_STATE | 1 | — |
READ_SMS | 1 | — |
RECEIVE_MMS | 1 | — |
RECEIVE_SMS | 1 | — |
RECEIVE_WAP_PUSH | 1 | — |
RECORD_AUDIO | 1 | — |
SEND_SMS | 1 | — |
WRITE_CALENDAR | 1 | — |
WRITE_CONTACTS | 1 | — |
WRITE_EXTERNAL_STORAGE | 4 | — |
USE_SIP | 9 | — |
ADD_VOICEMAIL | 14 | — |
READ_CALL_LOG | 16 | — |
READ_EXTERNAL_STORAGE | 16 | — |
WRITE_CALL_LOG | 16 | — |
BODY_SENSORS | 20 | — |
ANSWER_PHONE_CALLS | 26 | — |
READ_PHONE_NUMBERS | 26 | — |
ACCEPT_HANDOVER | 28 | — |
ACCESS_BACKGROUND_LOCATION | 29 | — |
ACCESS_MEDIA_LOCATION | 29 | — |
ACTIVITY_RECOGNITION | 29 | — |
BLUETOOTH_ADVERTISE | 31 | — |
BLUETOOTH_CONNECT | 31 | — |
BLUETOOTH_SCAN | 31 | — |
UWB_RANGING | 31 | — |
BODY_SENSORS_BACKGROUND | 33 | — |
NEARBY_WIFI_DEVICES | 33 | — |
POST_NOTIFICATIONS | 33 | — |
READ_MEDIA_AUDIO | 33 | — |
READ_MEDIA_IMAGES | 33 | — |
READ_MEDIA_VIDEO | 33 | — |
READ_MEDIA_VISUAL_USER_SELECTED | 34 | — |
RANGING | 36 | — |
ACCESS_LOCAL_NETWORK | 37 | — |
How it evolved#
Curiosity corner#
ACCESS_BACKGROUND_LOCATIONcannot be requested in the same dialog as foreground location, by design. The platform forces a second, deliberate step.
Try it#
adb shell dumpsys package com.example | grep -A40 "runtime permissions"
adb shell appops get com.example
Check yourself#
Check yourself
What does an API level identify?
Sources#
Sources
Every version number, API level, class name and date on this page is traced to one of these. Pages are re-verified against them; last_verified above says when.
- docsManifest.permission | API referencedeveloper.android.comaccessed 2026-10-27↩
- docsPermissions on Android | Privacydeveloper.android.comaccessed 2026-10-27↩