Skip to content
Bugwise
Menu
Features & Flows

App Permissions

How runtime permissions for camera, location, photos, notifications and more work on iOS and Android, what each answer means (allow, once, deny, don't ask again), what usually breaks, and how to reset and test permissions on every OS version.

35 min beginner Mobile

You order dinner, and the app wants to send you a photo review prompt. You tap Add photo, and the screen goes black. No camera, no message, no way out. What happened? Three weeks ago, on the very first launch, the app showed three permission pop-ups in a row and you tapped Don’t Allow on all of them, just to get to the menu. The app never recovered from that.

That’s what app permissionsApp permissionsThe user's approval for an app to use things like the camera, location, contacts or notifications.Open in glossary → bugs look like: the feature is fine, the code is fine “on the developer’s phone”, but one answer in a system dialog, given weeks ago, breaks it. Testers find these bugs because they deliberately try every answer, on every OS version, and change their mind in Settings.

How it works

Phones protect sensitive things (camera, microphone, location, photos, contacts) behind runtime permissions: the app must ask the user while it runs, through a system dialog the app can’t change or fake.

  1. The app declares what it may need. On iOS, each permission needs a purpose string in the app’s settings file (“We use your location to find your delivery address”); it’s shown in the dialog. On Android, the permission is listed in the app’s manifest. Without the declaration, the app can’t ask at all (on iOS it usually crashes when it tries).
  2. The app checks the current status. Not asked yet, allowed, allowed once, denied, or denied for good. It must check every time it needs the permission, because the user can change it any time in Settings.
  3. The app asks (if allowed to). Ideally right when the user starts the feature, after a short explanation in the app’s own UI (permission primingPermission primingExplaining in the app why a permission is needed, at the right moment, before the system dialog.Open in glossary →). The OS then shows its dialog.
  4. The user answers. Allow, allow once, or don’t allow. For location also precise or approximate.
  5. The app handles every answer. Allowed: the feature works. Denied: the feature explains what’s missing and offers Open Settings (a deep linkDeep linkA link that opens a specific screen inside an app instead of just its home screen.Open in glossary → to the app’s page in system Settings), and the rest of the app keeps working.
  6. The user changes their mind later. In system Settings, or the OS changes it automatically (one-time grants expire, unused apps lose permissions). The app must notice when it comes back.

The permissions you’ll meet

PermissioniOSAndroid
Camera, microphoneAllow / Don’t AllowWhile using / Only this time / Don’t allow
LocationAllow Once / While Using / Don’t Allow, plus Precise on/off. “Always” is a separate, later step.While using / Only this time / Don’t allow, plus Precise or Approximate. Background (“all the time”) only via Settings.
PhotosLimited (selected photos) or Full accessAndroid 14+: selected photos or all
ContactsAllow, or limited contacts (iOS 18+)Allow / Don’t allow
NotificationsAlways needs permissionNeeds permission since Android 13
BluetoothPermission since iOS 13“Nearby devices” since Android 12
TrackingApp Tracking Transparency (iOS 14.5+): “Ask App Not to Track” / “Allow”No equivalent dialog

Try the real dialogs

Pick a platform and a permission, then tap the answers to see what each means for the app and for your testing:

9:41

Snapbite

Allow “Snapbite” to use your location?

We use your location to find your delivery address.

iOS asks once. The map lets the user switch Precise off, so the app only gets an approximate area.

  • Allow

    “While Using App”: location works whenever the app is in use. “Always” (background location) can only be offered later, in a separate step.

  • Allow once

    Location works for this session only. When the app is no longer in use, the permission goes back to “ask”, and the app may show the dialog again next time.

  • Don’t allow

    The dialog will never appear again for this app. Only the Settings app can change the answer, so the app must explain that and link there.

Tap a button in the dialog to highlight what it means. Exact wording differs a little between OS versions and manufacturers.

Every answer is a test case

AnswerWhat the app getsWhat to test
Allow / While usingAccess whenever the app is in useThe feature works; still works after restart and update
Allow once / Only this timeAccess for now; it expires when the app is no longer in useNext launch: the app checks again and asks again, no silent failure
Don’t allow (first time)No access; Android may ask once moreThe app explains and keeps working
Denied for goodNo access, and the dialog will not appear againThe app shows an explanation with Open Settings, not a dead button
Approximate locationAn area of a few kilometersFeatures that need the street still work (confirm on a map, type the street)
Limited photosOnly the photos the user pickedThe app shows them and offers a way to pick more

“Don’t ask again”: when the dialog stops appearing

  • iOS shows each permission dialog once. After “Don’t Allow”, asking again does nothing: the OS silently returns “denied”. Only the Settings app can change it.
  • Android 11+ lets the app ask again after the first denial (usually after showing an explanation). After the second denial, Android stops showing the dialog and the request fails instantly. (Older Android versions had a “Don’t ask again” checkbox instead.)

So the classic bug is a “Turn on” button that calls the request again: on the developer’s phone it worked once, in real life it does nothing. Once the denial is final, the only working path is Open Settings.

Timing: ask in context

Asking for everything on the first launch is the fastest way to collect “Don’t Allow” answers. Ask when the user starts the feature, and explain the benefit first. The Onboarding lesson has a priming example, and Push Notifications shows why the first moment matters so much for the notification permission.

When permissions change while the app runs

Users can open Settings, change a permission and switch back to the app. What happens next depends on the OS, and it’s a rich source of crashes:

  • Android: revoking a runtime permission ends the app’s process. When the user returns, Android recreates the last screen from its saved state (state restorationState restorationBringing the user back to the same screen and data after the OS closed the app in the background.Open in glossary →). If that screen uses the camera or location without checking first, it crashes. Granting a permission does not restart the app.
  • iOS: for many privacy permissions (camera, microphone, photos, contacts), turning access off in Settings ends the app, which then starts fresh. Apple barely documents this, but it’s long-standing behavior you’ll see in practice. Location changes are usually reported to the running app instead. Either way, the app must re-check the status when it becomes active.

The OS changes permissions too

  • One-time grants expire: iOS “Allow Once” and Android “Only this time” are gone soon after the user leaves the app.
  • Auto-reset for unused apps (Android 11+): if an app isn’t opened for a few months, Android removes its runtime permissions. A user returning after a long break meets the dialogs again, or a denied state.
  • OS updates add new permissions: an app that worked on Android 12 may need the notification permission on Android 13, or the new photo permissions on Android 13 and 14. That’s why OS versionOS versionWhich version of iOS, Android or another operating system a device runs.Open in glossary → coverage matters here.

Example requirements

What usually goes wrong

#BugWhat you seeTypical severity
1Everything asked at launchThree dialogs in a row before the app appearsHigh (business)
2Blank feature after denialBlack camera view, empty map, endless spinnerHigh
3Dead “Turn on” buttonButton requests again; the OS ignores it once denial is finalHigh
4Approximate location breaks it“Couldn’t find your address” with precise location offHigh
5Crash after revokingApp crashes when the user returns from SettingsHigh
6“Allow once” treated as foreverWorks today, silently fails on the next launchMedium–High
7App state out of syncIn-app switch says “On”, but the OS denied the permissionMedium
8Missing purpose stringiOS crashes the moment the app asks for the cameraCritical
9New OS version not handledNo notification prompt on Android 13+, no photos on Android 14 with partial accessHigh
10Whole app blocked“This app needs location” screen with no way to continue without itMedium–High
11Asks too muchFull photo library or background location where less would doMedium (privacy, store review)
12Wrong or vague purpose text“This app needs camera” or text in the wrong languageLow–Medium

Find the bug

Snapbite, a food delivery app, has six permission bugs. Next to the phone you control the OS (iOS 18 or Android 15, each switch installs the app fresh), you can close and reopen the app or reinstall it, and you can change permissions in a system Settings panel while the app is open. The device log shows what the app asks the OS.

  • Open the app for the first time. What happens before you even see it?
  • Try every answer: Allow, Allow once / Only this time, Don’t allow, precise off.
  • After denying, try the feature again, and the button that should help.
  • Close and reopen the app after “Allow once”. Change permissions in Settings while you’re on the camera screen. Try it on both OS versions.

🐞 Bug hunt: Snapbite permissions

This demo has 6 hidden bugs. Explore it like a tester, then check your findings.

Found0/6
9:41

Freshly installed. Tap the icon to open the app for the first time.

Device

Switching OS installs the app fresh on that phone.

Settings › Snapbite

Changing a value here means: leave the app, change it in Settings, come back.

Precise Location

Now: location not asked, camera not asked, notifications not asked.

From the spec

  • Ask for each permission only when the user starts the feature that needs it.
  • If camera or location is denied, explain why it helps and offer “Open Settings”.
  • Approximate location must still work: show the area and let the user confirm the street.
  • Check the real permission status every time; a one-time grant means asking again later.
  • Changing permissions in Settings must never crash the app.

Device log

  • Open the app on the phone…
  1. 1

    Hint: Tap the app icon on a fresh install and count the dialogs.

  2. 2

    Hint: Deny the camera, then tap Add photo.

  3. 3

    Hint: On a fresh install deny location (twice on Android), then tap Use my current location and Turn on location.

  4. 4

    Hint: Allow location with Precise turned off (or Approximate on Android), then tap Use my current location.

  5. 5

    Hint: On Android 15, allow the camera, open Add photo, then set Camera to Don't allow in Settings.

  6. 6

    Hint: Choose Allow Once (or Only this time) for location at launch, use your location, then Close & reopen and try again.

Test scenarios

Functional

  • Each feature asks for its permission at the moment it’s needed, after an explanation.
  • Allow (or While using): the feature works now, after a restart, after an app update and after an OS update.
  • Allow once / Only this time: works now; next launch the app asks again and still works.
  • Limited photos and approximate location: the features still work with less access.
  • Open Settings buttons land on the app’s own page in system Settings.
  • Enabling a permission in Settings and returning: the feature starts working without restarting the app.

Negative

  • Don’t allow every permission on first use: the app still opens and the core flow (browse, order, pay) works.
  • Denied for good (iOS once, Android twice): the app shows an explanation with Open Settings, never a dead button or a blank screen.
  • Revoke each permission in Settings while the app is open, on the screen that uses it, then return.
  • Global switches off: Location Services off for the whole phone (iOS Settings › Privacy & Security), Bluetooth off, iOS “Allow Apps to Request to Track” off.

Edge cases

  • Fresh install vs update: a user who updates from an old version that never asked must be asked at the right moment, not all at once.
  • Auto-reset of unused apps (Android): permissions disappear without the user doing anything.
  • OS version boundaries: Android 12 vs 13 (notifications, photos), 13 vs 14 (partial photo access); iOS versions the app supports.
  • Manufacturer skins: Samsung and Xiaomi show their own permission and Settings screens (Device Fragmentation).
  • Dialog interrupted: a call or notification arrives while the system dialog is open (Interruptions); rotate the phone during the dialog.
  • Background location: if the app needs it (delivery drivers, run tracking), check the separate “Always / Allow all the time” step and the reminders the OS shows later.

UI & usability

  • The priming screen explains the benefit in one sentence and appears right before the system dialog.
  • Purpose strings (iOS) are specific, correct and translated into every supported language.
  • Denied states say what is missing, why it helps and how to fix it, with a working button.
  • The app never blocks everything because of one optional permission.

Security & privacy

  • The app asks for the minimum needed: photo picker instead of full library, approximate instead of precise, foreground instead of background, where possible.
  • Data collected with a permission stops being collected when it’s revoked (no cached location sent to the server afterwards).
  • On iOS, tracking happens only after “Allow” in the App Tracking Transparency dialog.
  • Permission answers are not tied to the user account: a second user on the same phone shares the OS permissions, so the app must not assume anything from the account.

Accessibility

How to reset and control permissions

You’ll reset permissions constantly: every time you want to see the first-time dialogs again, or test a denied state from scratch.

  • Delete and reinstall the app. The simplest reset: all of the app’s permission answers are forgotten. (Keychain data may survive; see Install, Update, Uninstall.)
  • Settings › [App]: change camera, photos, location (Never / Ask Next Time Or When I Share / While Using / Always, plus Precise Location) and notifications for one app. “Ask Next Time” lets the app show the location dialog again.
  • Reset all apps: Settings › General › Transfer or Reset iPhone › Reset › Reset Location & Privacy. Every app asks again. Useful on a shared test phone, annoying on your own.
  • Simulator: xcrun simctl privacy booted reset all com.example.snapbite resets the app’s privacy answers, and xcrun simctl privacy booted grant location com.example.snapbite grants one up front. Device › Erase All Content and Settings starts from zero. Use Features › Location to set a position.
  • OS versions: install older iOS simulator runtimes in Xcode, and keep at least one real device on the oldest supported version.
  • Settings › Apps › [App] › Permissions: set each permission to Allow, Ask every time, or Don’t allow, and toggle Use precise location. Choosing “Ask every time” also clears a final denial.
  • With adbadbAndroid Debug Bridge: a command-line tool for installing apps, reading logs and controlling Android devices.Open in glossary →:
    • adb shell pm revoke com.example.snapbite android.permission.CAMERA revokes one permission (the app’s process is killed, just like in Settings).
    • adb shell pm grant com.example.snapbite android.permission.CAMERA grants it without a dialog.
    • adb shell pm reset-permissions resets runtime permissions of all apps on the device.
    • adb shell pm clear com.example.snapbite wipes the app’s data and its permissions.
    • adb install -g snapbite.apk installs and grants all runtime permissions (handy for tests that aren’t about permissions).
  • Uninstall and reinstall also resets everything.
  • OS versions: create emulators for the oldest supported Android, Android 12, 13 and the newest version; each changed permissions. More in ADB basics and Simulators and Emulators.

Example test cases

TC-PERM-001No permission dialogs on first launch

Preconditions

  • Fresh install (or permissions reset)

Steps

  1. Open the app for the first time
  2. Browse restaurants

Expected result

No system permission dialog appears until the user starts a feature that needs one.

TC-PERM-002Location requested in context

Steps

  1. Open Delivery address
  2. Tap "Use my current location"
  3. Read the explanation and continue
  4. Choose While Using the App with Precise on

Expected result

An explanation appears before the system dialog. After allowing, the current street is suggested.

TC-PERM-003Final denial leads to Settings (iOS)

Preconditions

  • iOS device, location never asked

Steps

  1. Tap "Use my current location" and choose Don't Allow
  2. Tap the location button again

Expected result

The app explains that location is off and shows "Open Settings", which opens the app's page in Settings.

TC-PERM-004Second denial on Android

Preconditions

  • Android 11 or newer

Steps

  1. Deny the camera permission
  2. Tap Add photo again and read the explanation
  3. Deny again
  4. Tap Add photo a third time

Expected result

The dialog appears twice. After the second denial, the app shows an explanation with "Open Settings" instead of a blank camera.

TC-PERM-005Approximate location still helps

Steps

  1. Allow location with Precise off (iOS) or Approximate (Android)
  2. Tap "Use my current location"

Expected result

The app shows the approximate area and lets the user confirm or type the street. No error.

TC-PERM-006One-time permission asked again next launch

Steps

  1. Choose "Allow Once" / "Only this time" for location
  2. Use the feature
  3. Close the app completely and reopen it
  4. Use the feature again

Expected result

The app asks again (or explains) and the feature works after allowing. No endless spinner.

TC-PERM-007Revoke camera while the camera screen is open

Preconditions

  • Camera allowed
  • Run on Android and iOS

Steps

  1. Open Add photo
  2. Switch to Settings and set Camera to Don't allow / Off
  3. Return to the app

Expected result

No crash. The app shows the camera-off explanation or a fresh Home screen.

TC-PERM-008Permission granted in Settings is picked up

Preconditions

  • Camera denied for good

Steps

  1. Tap Add photo, then "Open Settings"
  2. Allow the camera
  3. Return to the app and tap Add photo

Expected result

The camera opens without reinstalling or restarting the app.

Tip: click a test case to expand it.

Mobile vs web

  • Browsers ask too: location, camera, microphone, notifications. The prompt belongs to the browser, and the answer is stored per site.
  • Users change it in the site settings (the icon next to the address bar). Test allow, block, and “allow this time” where the browser offers it.
  • Browsers may hide or block prompts that appear without a click, and Safari, Chrome and Firefox behave differently. Ask after a user action, never on page load.
  • Camera and location only work on HTTPS pages. On a plain HTTP staging site they fail, which is a test environment bug, not a product bug.
  • See Cross-Browser Testing for how to cover several browsers.

Checklist

App permissions checklist

0 of 14 checked

Check your understanding

Quick quiz

0/6 answered · 0 correct

  1. 1.On iOS a user tapped "Don't Allow" for the camera. What happens when the app requests the camera again?

  2. 2.On Android 13, when does the system stop showing the permission dialog for a permission?

  3. 3.A user chose "Allow Once" for location yesterday. Today the address spinner never stops. What is the most likely cause?

  4. 4.Which is the best way to show the iOS location dialog again on a test phone?

  5. 5.On Android you revoke the camera in Settings while the camera screen is open. When you return, the app crashes. Why?

  6. 6.A photo app asks for full photo library access just to set a profile picture. What should you suggest?

Key takeaways

  • Permissions are asked at runtime through system dialogs. Ask in context, after a short explanation, never all at once on launch.
  • Test every answer: allow, allow once, don’t allow, denied for good, approximate location, limited photos.
  • iOS asks once, Android up to twice. After that only Open Settings helps; a “Turn on” button that just asks again is a bug.
  • Permissions change behind the app’s back: Settings, one-time expiry, auto-reset, OS updates. The app must re-check every time and never crash when the user returns.
  • Reset permissions often (reinstall, Settings, adb shell pm, xcrun simctl privacy) and test on old and new OS versions of both platforms.

Finished this page?Nice work, this page is complete!

Mark it as done to track your progress. It's saved in this browser, no account needed.

Its review cards are now in Bites ⚡
Esc

Type to search the whole site.