Handling Permissions
1. Using PermissionsAndroid
| Permission | Constant | Description | Platform |
|---|---|---|---|
| ACCESS_COARSE_LOCATION | PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION |
Allows access to approximate location | Android |
| ACCESS_FINE_LOCATION | PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION |
Allows access to precise location | Android |
| CAMERA | PermissionsAndroid.PERMISSIONS.CAMERA |
Allows access to camera | Android |
| READ_CONTACTS | PermissionsAndroid.PERMISSIONS.READ_CONTACTS |
Allows reading contacts | Android |
| WRITE_CONTACTS | PermissionsAndroid.PERMISSIONS.WRITE_CONTACTS |
Allows writing contacts | Android |
| READ_EXTERNAL_STORAGE | PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE |
Allows reading external storage | Android |
| WRITE_EXTERNAL_STORAGE | PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE |
Allows writing to external storage | Android |
| RECORD_AUDIO | PermissionsAndroid.PERMISSIONS.RECORD_AUDIO |
Allows recording audio | Android |
| WRITE_SETTINGS | PermissionsAndroid.PERMISSIONS.WRITE_SETTINGS |
Allows modifying system settings | Android |
Example: Requesting Camera Permission
import { PermissionsAndroid } from 'react-native';
const requestCameraPermission = async () => {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message: 'App needs access to your camera to take photos.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Camera permission granted');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
};
Example: Checking Location Permission
import { PermissionsAndroid } from 'react-native';
const checkLocationPermission = async () => {
try {
const granted = await PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
);
if (granted) {
console.log('Location permission granted');
} else {
console.log('Location permission denied');
}
} catch (err) {
console.warn(err);
}
};
Note: On Android 6.0 (API level 23) and above, you must explicitly request permissions at runtime.
2. Requesting iOS Permissions
| Permission | Usage | Notes |
|---|---|---|
| NSCameraUsageDescription | camera |
Required for camera access. Must provide a description in Info.plist. |
| NSPhotoLibraryUsageDescription | photoLibrary |
Required for accessing the photo library. Must provide a description in Info.plist. |
| NSLocationWhenInUseUsageDescription | location |
Required for location access when app is in use. Must provide a description in Info.plist. |
| NSLocationAlwaysAndWhenInUseUsageDescription | location |
Required for location access at all times. Must provide a description in Info.plist. |
| NSMicrophoneUsageDescription | microphone |
Required for microphone access. Must provide a description in Info.plist. |
| NSBluetoothAlwaysUsageDescription | bluetooth |
Required for Bluetooth access. Must provide a description in Info.plist. |
Example: Requesting Camera Permission
import { PermissionsAndroid, Platform } from 'react-native';
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message: 'App needs camera permission to take photos.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Camera permission granted');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
}
};
Note: For iOS, you must add the appropriate keys to your
Info.plist file and provide a usage description for each permission you request.
3. Checking Permission Status
| Permission | Status | Description |
|---|---|---|
| camera | granted, denied, undetermined |
User has granted, denied, or not yet decided on camera access |
| location | granted, denied, undetermined |
User has granted, denied, or not yet decided on location access |
| microphone | granted, denied, undetermined |
User has granted, denied, or not yet decided on microphone access |
| photoLibrary | granted, denied, undetermined |
User has granted, denied, or not yet decided on photo library access |
Example: Check Camera Permission
import { PermissionsAndroid, Platform } from 'react-native';
const checkCameraPermission = async () => {
if (Platform.OS === 'android') {
const permission = PermissionsAndroid.PERMISSIONS.CAMERA;
const status = await PermissionsAndroid.check(permission);
console.log('Camera permission status:', status);
}
};
4. Requesting Runtime Permissions
| Permission | Android | iOS | Notes |
|---|---|---|---|
| ACCESS_FINE_LOCATION | ACCESS_FINE_LOCATION |
NSLocationWhenInUseUsageDescription |
Required for precise location data |
| CAMERA | CAMERA |
NSCameraUsageDescription |
Access to device camera |
| RECORD_AUDIO | RECORD_AUDIO |
NSMicrophoneUsageDescription |
Access to microphone for audio recording |
| READ_CONTACTS | READ_CONTACTS |
NSContactsUsageDescription |
Read contact list from device |
| WRITE_EXTERNAL_STORAGE | WRITE_EXTERNAL_STORAGE |
NSPhotoLibraryUsageDescription |
Write to external storage or photo library |
Example: Requesting Camera Permission
import { PermissionsAndroid, Platform } from 'react-native';
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message: 'App needs access to your camera ' +
'to take pictures.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Camera permission granted');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
}
};
Note: On iOS, you must add the appropriate usage description keys to your
Info.plist file for each permission you request.
Warning: Runtime permissions must be requested at runtime, not during app initialization. Always check the permission status before attempting to use a feature.
5. Handling Permission Denials
Example: Requesting Camera Permission
import { PermissionsAndroid, Platform } from 'react-native';
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message: 'App needs camera access to take photos',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Camera permission granted');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
}
};
| Permission | Android Constant | Usage | Notes |
|---|---|---|---|
| CAMERA | PermissionsAndroid.PERMISSIONS.CAMERA |
Access camera for photos/videos | Requires android.permission.CAMERA |
| ACCESS_FINE_LOCATION | PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION |
Access precise location data | May require ACCESS_COARSE_LOCATION |
| READ_CONTACTS | PermissionsAndroid.PERMISSIONS.READ_CONTACTS |
Read contact list | Requires android.permission.READ_CONTACTS |
Handling Permission Denial Workflow
- User denies permission in system dialog
- App receives
PermissionsAndroid.RESULTS.DENIED - App should show user-friendly message or alternative flow
- Optionally, guide user to settings to enable permission manually
Note: On Android, if a user denies permission and selects "Don't ask again", the system will not show the permission dialog again. You must guide the user to manually enable permissions in Settings.
Permission Result Types
- GRANTED: Permission was accepted
- DENIED: User denied the permission once
- NEVER_ASK_AGAIN: User denied and checked "Don't ask again"
6. Implementing Permission Rationale
Example: Requesting Camera Permission with Rationale
import { PermissionsAndroid, Platform } from 'react-native';
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message:
'App needs access to your camera ' +
'to take photos.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Camera permission granted');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
}
};
| Permission | Android Constant | Description | Notes |
|---|---|---|---|
| CAMERA | PermissionsAndroid.PERMISSIONS.CAMERA |
Access to camera hardware | Requires android.permission.CAMERA |
| ACCESS_FINE_LOCATION | PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION |
Access to precise location data | May require android.permission.ACCESS_FINE_LOCATION |
| STORAGE | PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE |
Write access to external storage | Deprecated in Android 10+; use MANAGE_EXTERNAL_STORAGE for full access |
Note: On Android,
PermissionsAndroid.request returns a Promise that resolves to one of the following constants: RESULTS.GRANTED, RESULTS.DENIED, RESULTS.NEVER_ASK_AGAIN.
Warning: On Android 6.0 (API level 23) and above, you must explicitly request permissions at runtime. Permissions requested in the manifest are not sufficient.
7. Opening App Settings
| Permission | Android | iOS |
|---|---|---|
| android.permission.ACCESS_FINE_LOCATION | ACCESS_FINE_LOCATION |
LOCATION |
| android.permission.CAMERA | CAMERA |
CAMERA |
| android.permission.RECORD_AUDIO | RECORD_AUDIO |
MICROPHONE |
| android.permission.READ_CONTACTS | READ_CONTACTS |
CONTACTS |
| android.permission.READ_EXTERNAL_STORAGE | READ_EXTERNAL_STORAGE |
PHOTOS |
Example: Opening App Settings
import { openSettings } from 'react-native-settings-app';
const openAppSettings = () => {
openSettings();
};
Note: On iOS,
openSettings opens the app's settings page directly. On Android, it opens the system settings where users can manage permissions for the app.
8. Managing Multiple Permissions
Example: Requesting Multiple Permissions
import { PermissionsAndroid, Platform } from 'react-native';
const requestMultiplePermissions = async () => {
if (Platform.OS === 'android') {
const results = await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.CAMERA,
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
]);
console.log('Camera permission:', results[PermissionsAndroid.PERMISSIONS.CAMERA]);
console.log('Contacts permission:', results[PermissionsAndroid.PERMISSIONS.READ_CONTACTS]);
console.log('Location permission:', results[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION]);
}
};
requestMultiplePermissions();
| Permission | Android Constant | Description | Required in Manifest |
|---|---|---|---|
| CAMERA | PermissionsAndroid.PERMISSIONS.CAMERA |
Access to camera hardware | Yes |
| READ_CONTACTS | PermissionsAndroid.PERMISSIONS.READ_CONTACTS |
Read contact data | Yes |
| ACCESS_FINE_LOCATION | PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION |
Access precise location data | Yes |
| WRITE_EXTERNAL_STORAGE | PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE |
Write to external storage | Yes |
| RECORD_AUDIO | PermissionsAndroid.PERMISSIONS.RECORD_AUDIO |
Record audio | Yes |
Permission Request Results
granted: User has granted the permissiondenied: User has denied the permissionnever_ask_again: User has denied and checked "never ask again"
Workflow for Handling Multiple Permissions
- Import
PermissionsAndroidfromreact-native - Define the list of permissions to request
- Call
PermissionsAndroid.requestMultiple()with the list - Handle the returned object containing permission statuses
- Implement logic to respond to each permission status
Note: On Android,
requestMultiple returns a promise that resolves to an object mapping permission constants to their status strings.
Warning: Always check the platform before requesting permissions to avoid errors on iOS.
9. Testing Permission Flows
Example: Requesting Camera Permission
import { PermissionsAndroid, Platform } from 'react-native';
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message: 'App needs camera access to take photos',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Camera permission granted');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
}
};
| Permission | Android Constant | Usage | Notes |
|---|---|---|---|
| CAMERA | PermissionsAndroid.PERMISSIONS.CAMERA |
Access camera hardware | Requires android.permission.CAMERA in manifest |
| ACCESS_FINE_LOCATION | PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION |
Access precise location data | Also requires ACCESS_COARSE_LOCATION |
| READ_CONTACTS | PermissionsAndroid.PERMISSIONS.READ_CONTACTS |
Read contact list | May require READ_PROFILE for some devices |
Note: On Android, permissions must be declared in
AndroidManifest.xml before use.
Permission Request Workflow
- Check if permission is already granted
- Request permission using
PermissionsAndroid.request() - Handle the result (granted/denied)
- Implement fallback behavior if denied
Permission Request Types
- Single Permission: Request one permission at a time
- Multiple Permissions: Use
PermissionsAndroid.PERMISSIONSarray - Runtime vs Build-time: Runtime permissions require user interaction
10. Using react-native-permissions
Example: Requesting Camera Permission
import { PermissionsAndroid, Platform } from 'react-native';
import { request, PERMISSIONS } from 'react-native-permissions';
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA,
{
title: 'Camera Permission',
message: 'App needs camera access to take photos',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Camera permission granted');
} else {
console.log('Camera permission denied');
}
} catch (err) {
console.warn(err);
}
}
};
| Permission | Android | iOS | Description |
|---|---|---|---|
| CAMERA | CAMERA |
camera |
Access to camera hardware |
| LOCATION | ACCESS_FINE_LOCATION |
location |
Access to precise location data |
| STORAGE | WRITE_EXTERNAL_STORAGE |
photoLibrary |
Read/write access to external storage |
Note: On iOS, permissions are requested at runtime and must be declared in
Info.plist.