← Back to Cross-platform mobile foundation team
See how it helps
Mobile device permissions
Implements contextual access to device features with minimal permissions and explicit denied or revoked states.
mobile-device-permissions
Team members using this skill
When is it useful?
Use when adding camera, media selection or biometric authentication.
What does it help you do?
- Prefers system pickers that avoid unnecessary broad access.
- Models request, denial, permanent denial and later revocation.
- Handles temporary media files and native permission configuration.
Try asking this
Add photo attachment through a system picker and preserve the draft when camera access is denied. Deny camera access, choose an existing photo instead and return from the picker. Keep the draft intact and release unused temporary files.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Device Features & Permissions
Integrate camera, media, files, geolocation, biometrics and sensors using the principle of least privilege, contextual permission prompts and full recovery when permissions are denied or revoked.
1. Zero-permission system pickers and least-privilege APIs
- Avoid broad storage/library permissions when a system picker suffices:
- Photos & Videos: use the system Photo Picker (
PHPickerViewController/ Android Photo Picker viaexpo-image-pickerorimage_picker), granting one-time read access to selected items withoutREAD_MEDIA_IMAGESor fullNSPhotoLibraryUsageDescriptionaccess. - Documents & Files: use the system Document Picker (
UIDocumentPickerViewController/ Android SAFACTION_OPEN_DOCUMENT) rather than broad storage permissions. - Location: request Approximate / Coarse (
ACCESS_COARSE_LOCATION) when city/region accuracy suffices, and When In Use (NSLocationWhenInUseUsageDescription/ACCESS_FINE_LOCATION) before escalating toAlways.
- Photos & Videos: use the system Photo Picker (
2. Contextual permission state machine
- Never request permissions on app startup: ask only when the user taps the action ("Scan QR code", "Find nearby stores", "Record voice note").
- Handle all 5 OS permission states explicitly:
| Permission Status | Required Application Behavior |
|---|---|
undetermined / notDetermined |
Show brief contextual explanation if non-obvious, then trigger the native OS prompt. |
granted |
Start the hardware feature and clean up on screen exit or app backgrounding. |
limited (iOS Photos / Coarse Location) |
Operate smoothly on selected photos or coarse coordinates; offer a button to "Manage selected photos" (presentLimitedLibraryPicker) or upgrade precision if needed. |
denied (can ask again on Android) |
Keep the screen usable; explain why the feature needs the permission and allow retrying when the user taps the action again. |
blocked / permanentlyDenied |
The OS will not re-prompt (canAskAgain === false). Show a clear inline fallback with an "Open Settings" button (Linking.openSettings() / openAppSettings()) and a manual alternative (e.g., manual address entry or file upload). |
- Re-check on foreground resume: users returning from OS Settings may have granted or revoked the permission; listen to
AppState/AppLifecycleListenerand refresh the permission state automatically.
3. Camera, media processing and temporary file hygiene
- Hardware lifecycle: pause/release camera preview sessions, barcode scanners, audio recorders, Bluetooth scans and GPS watchers immediately when the screen blurs/unmounts or the app enters
background. - Off-thread media compression & EXIF privacy: resize and compress captured photos/videos off the UI thread before upload, respect EXIF orientation, strip sensitive GPS EXIF metadata when sharing publicly, and delete temp files from
Caches/cacheDirectoryonce upload completes. - Simulator & missing-hardware fallback: check hardware availability (
Camera.isAvailableAsync(), sensor availability, simulator camera absence) and provide a file-picker or mock fallback so development and tablets without rear cameras never crash.
4. Biometrics and App Store / Google Play compliance
- Cryptographic biometric binding: use Face ID / Touch ID (
LocalAuthentication) and AndroidBiometricPromptto unlock a credential stored in the hardware-backed Keychain / Keystore (requireAuthentication: trueinexpo-secure-store,CryptoObjectinBiometricPrompt)—never as a client-only booleanif (authenticated) setLoggedIn(true)gate without a cryptographic session token. - Store review compliance: write concrete iOS
Info.plistNS...UsageDescriptionstrings explaining the exact user benefit (vague strings cause immediate App Store rejection) and declare<uses-feature android:name="android.hardware.camera" android:required="false" />on Android when hardware is optional.
Before you finish
- System pickers used where possible; only minimal required permissions declared in
Info.plist/AndroidManifest.xml. -
undetermined,granted,limited,deniedandblocked(withopenSettings) states all work. - Permission status re-syncs on foreground resume; camera/audio/GPS sessions stop on blur/background.
- Biometrics unlock Keychain/Keystore credentials; temp media files are cleaned up after use.
Included files 2
LICENSE.txtSKILL.md
