Introduction
Modern mobile apps often need access to device features like the camera, location, contacts, and storage. While these capabilities enhance functionality, they also raise privacy concerns and introduce complexity. Users are increasingly cautious about what they allow—mismanaging permissions can lead to uninstalls, bad reviews, or app store rejection.

This guide covers how to handle mobile app permissions properly on both iOS and Android. You’ll learn when and how to request permissions, manage them at runtime, comply with platform guidelines, and build user trust through transparency.
Why Permissions Matter
1. User Trust
Requesting too many permissions upfront—or at the wrong time—can scare users away.
2. Privacy Regulations
Laws like GDPR and CCPA require informed consent and careful handling of personal data.
3. App Store Compliance
Apple and Google have strict policies around sensitive permissions. Poor implementation can lead to app rejections.
4. App Functionality
If a user denies a required permission (like camera or location), core features may break unless handled gracefully.
Common Permissions in Mobile Apps
Permission | Purpose | Platform Notes |
---|---|---|
Location | Maps, geofencing, delivery tracking | Requires justification + privacy policy |
Camera | Image capture, video calls | Explain use clearly (e.g., profile photos) |
Microphone | Audio recording, voice chat | Sensitive – ask only when needed |
Contacts | Social or referral features | High friction—avoid unless essential |
Storage/Files | Uploads, downloads, file access | Scoped storage recommended on Android |
Notifications | User engagement, alerts | Explicit opt-in (iOS 13+, Android 13+) |
Bluetooth | Device pairing, proximity detection | Requires explanation on iOS (NSBluetooth) |
Best Practices for Handling Permissions
1. Request Permissions Contextually
Ask for a permission right before it’s needed, not at app launch.
✅ Good Example:
Ask for camera access when the user taps “Upload Profile Picture.”
❌ Bad Example:
Request all permissions during onboarding.
2. Provide a Clear Justification
Always explain why you need a permission. This builds trust and improves acceptance rates.

iOS – Use NS...UsageDescription
in Info.plist
xmlCopyEdit<key>NSCameraUsageDescription</key>
<string>We need access to your camera to scan documents</string>
Android – Use in-app dialog before system prompt
javaCopyEditnew AlertDialog.Builder(this)
.setTitle("Camera Access Required")
.setMessage("To take profile photos, the app needs access to your camera.")
.setPositiveButton("OK", (dialog, which) -> {
requestPermissions(...);
}).show();
3. Use Platform APIs for Runtime Permissions
Android (6.0+)
javaCopyEditif (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
CAMERA_REQUEST_CODE);
}
iOS (Post iOS 10)
iOS handles permission requests internally, but you can pre-check availability:
swiftCopyEditswitch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
// Access granted
case .notDetermined:
AVCaptureDevice.requestAccess(for: .video) { granted in ... }
default:
// Show rationale or redirect to settings
}
4. Handle Denied or Restricted Permissions Gracefully
If a user denies a permission, never crash the app. Provide alternatives or guide them to settings.
Example:
javascriptCopyEditif (!hasPermission) {
Alert.alert(
"Permission Required",
"Camera access is needed to scan your ID. Please enable it in settings.",
[
{ text: "Cancel" },
{ text: "Open Settings", onPress: () => Linking.openSettings() }
]
);
}
5. Check Permissions on App Resume
Users can change permissions anytime. Check the status when your app regains focus.

React Native Example:
javascriptCopyEditAppState.addEventListener("change", nextState => {
if (nextState === "active") {
checkPermissions();
}
});
6. Use Permission Libraries for Simplification
React Native:
react-native-permissions
expo-permissions
(for Expo apps)
Android:
- Jetpack’s
ActivityResultContracts.RequestPermission()
iOS:
PermissionScope
,SPPermissions
(third-party Swift libraries)
These tools help manage permission flows consistently across platforms.
How to Explain Permissions to Users
Use plain language and show the value to the user:
“We need your location to show nearby deals.”
Avoid vague or technical reasons:
❌ “Enable GPS to access the API.”
Combine permissions with progressive disclosure: only reveal deeper features once a permission is granted.
Dealing with App Store Rejections
Apple and Google have increased scrutiny on permissions. Avoid rejection by:
- Only requesting necessary permissions
- Justifying them in app metadata and privacy policy
- Handling denied permissions safely
- Avoiding silent access to restricted data (e.g., clipboard, background location)
Testing Permissions Thoroughly

Test each scenario:
- First-time request
- User denies once
- User selects “Don’t ask again”
- Permission revoked manually in settings
- Permissions granted temporarily (Android 11+)
Simulate permission states using:
- Xcode simulators (
Features > Location > None/Custom
) - ADB commands on Android:
bashCopyEditadb shell pm revoke com.yourapp android.permission.CAMERA
Real-World Example: Scanning Receipts with Camera Access
Feature: Users upload receipts using camera
Flow:
- User taps “Scan Receipt”
- App checks if camera permission is granted
- If not, shows rationale dialog
- On approval, launches camera
- If denied, prompts to go to settings or upload a file instead
This approach respects the user’s control while offering alternatives.
Conclusion
Managing permissions in mobile apps isn’t just about satisfying technical requirements—it’s about respecting user trust and providing a seamless experience. By asking for the right permissions at the right time, clearly explaining their value, and handling every edge case gracefully, you can create apps that are both powerful and privacy-conscious.
As privacy regulations tighten and users grow more cautious, mastering permission handling isn’t optional—it’s a core skill for every mobile developer.