Android permissions come in two layers: every permission an app uses must be declared in the manifest, and the subset classified as dangerous must additionally be requested at runtime, where the user grants or denies them. Normal permissions, like internet access, are granted automatically at install once declared. Dangerous permissions, like camera, microphone, location, contacts, and SMS, require a runtime prompt from Android 6.0 onward, and the user can refuse. Declare only what you use, request dangerous permissions in context when the feature needs them, and handle denial gracefully, because requesting permissions you cannot justify is both a privacy issue and a common cause of store rejection.
Short answer
Every permission is declared in the manifest, and dangerous ones are also requested at runtime. Per Android's permissions overview, normal permissions are granted automatically at install, signature permissions go to apps signed with the same certificate, and dangerous permissions require a runtime request the user can approve or deny. The dangerous list, defined in Manifest.permission, covers access to sensitive data and features: location, camera, microphone, contacts, SMS, phone, calendar, body sensors, and media. Request only what you genuinely need, ask in context, and handle denial. Over-requesting dangerous permissions is a privacy risk and a frequent reason apps are rejected.
Manifest vs runtime permissions
The manifest and runtime layers do different jobs. Declaring a permission in AndroidManifest.xml tells the system your app may use it, and this declaration is required for every permission, normal or dangerous. Without the manifest entry, the permission is not available to your app at all, so the manifest is the complete list of what your app can request.
The runtime layer applies only to dangerous permissions. From Android 6.0, API level 23, onward, declaring a dangerous permission in the manifest is not enough; you must also ask the user for it at runtime, and they can grant or deny it. Normal permissions never need a runtime request. So the rule is simple: declare everything in the manifest, and additionally request the dangerous ones at runtime, checking whether they are granted before using the protected feature.
Protection levels: normal, signature, dangerous
Android classifies permissions by protection level, which decides how they are granted. Normal permissions, such as internet access, cover low-risk capabilities and are granted automatically at install once declared, with no user prompt. They are safe by design because they do not touch sensitive user data.
Signature permissions are granted only to apps signed with the same certificate as the app that defined the permission, which is used for trusted communication between your own apps. Dangerous permissions cover access to sensitive data or features and require the runtime request the user must approve. There are also special permissions, like drawing over other apps or managing all files, which use a dedicated settings flow rather than the standard runtime dialog because of their broad power.
The dangerous permissions list
The dangerous permissions are those that access sensitive user data or device features, grouped by the kind of data they protect. They include location, with fine, coarse, and background variants; camera; microphone through record audio; contacts; SMS, including send, read, and receive; phone state and calls; calendar; body sensors; and, on newer Android, granular media permissions for images, video, and audio, plus posting notifications.
Each of these requires a runtime request, and the user can deny any of them. Because they map directly to sensitive capabilities, they are also the permissions that draw scrutiny in review and that matter most for privacy. The practical implication is to treat the dangerous list as the set you request sparingly and justify clearly, since every dangerous permission you add is something the user can refuse and something a reviewer may question.
How to request a runtime permission
Requesting a dangerous permission at runtime follows a clear sequence. First, check whether the permission is already granted, since the user may have granted it before. If it is not, request it, which shows the system dialog asking the user to allow or deny. When the user responds, your app receives the result and either proceeds with the feature or handles the denial.
Request in context, at the moment the feature actually needs the permission, rather than all at once on launch. Asking for the camera when the user taps to take a photo is far more likely to be granted, and far less alarming, than requesting camera, location, and contacts on first open. Requesting in context, with the feature the permission enables visible to the user, is both better for grant rates and aligned with how Android expects permissions to be used.
Handling denial gracefully
Because the user can deny any dangerous permission, your app must handle denial without breaking. When a permission is refused, the corresponding feature should degrade gracefully: disable just that feature, explain why it is unavailable, and let the rest of the app work. An app that crashes or becomes unusable after a denied permission is both a poor experience and a likely rejection.
Android also lets you check whether to show a rationale, so that if the user previously denied a permission you can explain why the feature needs it before asking again. Use that to give a short, honest reason rather than repeatedly prompting. Respecting a denial, and only re-asking with a clear explanation when the user tries to use the feature again, keeps your app usable and your permission requests trustworthy.
Permission types compared
Seeing the levels together clarifies how each is granted. The table below compares them.
| Level | Example | How it is granted |
|---|---|---|
| Normal | Internet access | Automatically at install, no prompt |
| Signature | A custom same-signature permission | Only to apps signed with the same certificate |
| Dangerous | Camera, fine location, contacts | Runtime request the user can deny |
| Special | Draw over other apps, manage all files | A dedicated settings flow |
Read the table to place each permission your app uses. Most apps combine a few normal permissions, granted silently, with a small set of dangerous ones that need runtime requests, and should avoid special permissions unless the app genuinely requires that broad access.
Best-practice checklist
Handling permissions well is a short set of habits. The checklist below captures them.
| Check | Action | Done? |
|---|---|---|
| Declare in manifest | Add every permission the app actually uses | [ ] |
| Minimize | Request only what a feature genuinely needs | [ ] |
| Request in context | Ask when the user invokes the feature | [ ] |
| Handle denial | Degrade the feature gracefully, do not crash | [ ] |
| Justify dangerous ones | Only request dangerous permissions you can explain | [ ] |
The two that matter most for privacy and review are minimizing what you request and justifying every dangerous permission, since an unused or unexplained dangerous permission is exactly what raises a privacy concern and a reviewer's question. Requesting in context and handling denial then keep the experience clean.
Scan for over-permissioning
Over-permissioning, requesting dangerous permissions the app does not need, is one of the most common and avoidable issues in mobile apps, and it is easy to accumulate, especially when a library or generated code pulls in a permission you never intended. It is a privacy risk and a frequent reason apps are questioned or rejected.
A scanner like PTKD.com analyzes your app build and reports findings ordered by severity and mapped to OWASP MASVS, including over-broad or unjustified permissions, so you can see exactly what your app requests and trim what it does not need. To be clear about the boundary: PTKD does not write your permission requests or handle denials in code. It surfaces the permissions your build actually declares so you can minimize them before shipping.
What to take away
- Every permission is declared in the manifest; dangerous permissions must additionally be requested at runtime, where the user can deny them.
- Protection levels are normal, granted at install; signature, for same-certificate apps; and dangerous, requiring a runtime request, plus special permissions with their own flow.
- The dangerous list covers location, camera, microphone, contacts, SMS, phone, calendar, sensors, and media, and each needs runtime consent.
- Request in context, minimize what you ask for, justify every dangerous permission, and handle denial gracefully rather than crashing.
- Scan with PTKD.com to catch over-broad permissions and trim what your app does not need before shipping.


