Functions and React hooks for managing camera and media library permissions across platforms.
Functions and hooks for managing camera access permissions.
/**
* Checks user's permissions for accessing camera.
* @returns Promise resolving to current camera permission status
*/
function getCameraPermissionsAsync(): Promise<CameraPermissionResponse>;
/**
* Asks the user to grant permissions for accessing camera.
* This does nothing on web because the browser camera is not used.
* @returns Promise resolving to camera permission response after request
*/
function requestCameraPermissionsAsync(): Promise<CameraPermissionResponse>;
/**
* React hook for camera permissions management.
* Combines both checking and requesting permissions.
* @param options Optional configuration for the permission hook
* @returns Tuple of [status, requestPermission, getPermission]
*/
const useCameraPermissions: (
options?: PermissionHookOptions
) => [
PermissionResponse | null,
() => Promise<PermissionResponse>,
() => Promise<PermissionResponse>
];Usage Examples:
import * as ImagePicker from 'expo-image-picker';
// Check camera permissions
const checkCameraPermissions = async () => {
const { status, canAskAgain } = await ImagePicker.getCameraPermissionsAsync();
console.log('Camera permission status:', status);
if (status === 'denied' && !canAskAgain) {
// User permanently denied, direct to settings
alert('Camera access permanently denied. Please enable in settings.');
}
};
// Request camera permissions
const requestCameraAccess = async () => {
const { status } = await ImagePicker.requestCameraPermissionsAsync();
if (status === 'granted') {
console.log('Camera access granted');
// Proceed with camera functionality
} else {
console.log('Camera access denied');
}
};
// Using camera permissions hook
import { useCameraPermissions } from 'expo-image-picker';
function CameraComponent() {
const [status, requestPermission] = useCameraPermissions();
const handleCameraPress = async () => {
if (status?.granted) {
// Permission already granted
launchCamera();
} else {
// Request permission
const newStatus = await requestPermission();
if (newStatus.granted) {
launchCamera();
}
}
};
const launchCamera = async () => {
const result = await ImagePicker.launchCameraAsync({
mediaTypes: 'images',
quality: 0.8,
});
};
return (
<button onClick={handleCameraPress}>
{status?.granted ? 'Take Photo' : 'Grant Camera Permission'}
</button>
);
}Functions and hooks for managing photo library access permissions.
/**
* Checks user's permissions for accessing photos.
* @param writeOnly Whether to check write-only or read-write permissions (default: false)
* @returns Promise resolving to current media library permission status
*/
function getMediaLibraryPermissionsAsync(
writeOnly?: boolean
): Promise<MediaLibraryPermissionResponse>;
/**
* Asks the user to grant permissions for accessing user's photos.
* This method does nothing on web.
* @param writeOnly Whether to request write-only or read-write permissions (default: false)
* @returns Promise resolving to media library permission response after request
*/
function requestMediaLibraryPermissionsAsync(
writeOnly?: boolean
): Promise<MediaLibraryPermissionResponse>;
/**
* React hook for media library permissions management.
* Combines both checking and requesting permissions.
* @param options Optional configuration including writeOnly setting
* @returns Tuple of [status, requestPermission, getPermission]
*/
const useMediaLibraryPermissions: (
options?: PermissionHookOptions<{ writeOnly?: boolean }>
) => [
MediaLibraryPermissionResponse | null,
() => Promise<MediaLibraryPermissionResponse>,
() => Promise<MediaLibraryPermissionResponse>
];Usage Examples:
import * as ImagePicker from 'expo-image-picker';
// Check media library permissions
const checkLibraryPermissions = async () => {
const { status, accessPrivileges } = await ImagePicker.getMediaLibraryPermissionsAsync();
console.log('Library permission status:', status);
console.log('Access privileges:', accessPrivileges);
if (accessPrivileges === 'limited') {
console.log('User granted limited photo access');
}
};
// Request full media library access
const requestLibraryAccess = async () => {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync(false);
if (status === 'granted') {
console.log('Full media library access granted');
} else {
console.log('Media library access denied');
}
};
// Request write-only permissions (for saving photos)
const requestWriteAccess = async () => {
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync(true);
if (status === 'granted') {
console.log('Write access granted');
}
};
// Using media library permissions hook
import { useMediaLibraryPermissions } from 'expo-image-picker';
function PhotoLibraryComponent() {
const [status, requestPermission] = useMediaLibraryPermissions();
const handleLibraryPress = async () => {
if (status?.granted) {
// Permission already granted
openLibrary();
} else {
// Request permission
const newStatus = await requestPermission();
if (newStatus.granted) {
openLibrary();
}
}
};
const openLibrary = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: 'images',
allowsMultipleSelection: true,
quality: 0.8,
});
};
const getStatusMessage = () => {
if (!status) return 'Checking permissions...';
if (status.granted) {
if (status.accessPrivileges === 'limited') {
return 'Limited photo access granted';
}
return 'Full photo access granted';
}
return 'Photo access required';
};
return (
<div>
<p>{getStatusMessage()}</p>
<button onClick={handleLibraryPress}>
{status?.granted ? 'Open Photo Library' : 'Grant Library Permission'}
</button>
</div>
);
}// Camera permission type (alias of PermissionResponse)
type CameraPermissionResponse = PermissionResponse;
// Media library permission type (extends PermissionResponse)
interface MediaLibraryPermissionResponse extends PermissionResponse {
/**
* iOS/Android 34+ specific field indicating level of photo access:
* - 'all': Full photo library access
* - 'limited': Access to selected photos only
* - 'none': No access granted
*/
accessPrivileges?: 'all' | 'limited' | 'none';
}
// Base permission response (from expo-modules-core)
interface PermissionResponse {
status: PermissionStatus;
expires: PermissionExpiration;
granted: boolean;
canAskAgain: boolean;
}
enum PermissionStatus {
DENIED = 'denied',
GRANTED = 'granted',
UNDETERMINED = 'undetermined'
}
type PermissionExpiration = 'never' | number;
// Hook options
interface PermissionHookOptions<T = object> {
get?: boolean;
request?: boolean;
} & T;import * as ImagePicker from 'expo-image-picker';
const handleImageSelection = async () => {
// 1. Check current permission status
const { status, canAskAgain } = await ImagePicker.getMediaLibraryPermissionsAsync();
if (status === 'granted') {
// Permission already granted - proceed
launchLibrary();
} else if (status === 'denied') {
if (canAskAgain) {
// Can ask again - request permission
const result = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (result.status === 'granted') {
launchLibrary();
} else {
showPermissionDeniedMessage();
}
} else {
// Permission permanently denied - direct to settings
showSettingsAlert();
}
} else {
// Status is 'undetermined' - request permission
const result = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (result.status === 'granted') {
launchLibrary();
} else {
showPermissionDeniedMessage();
}
}
};
const launchLibrary = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: 'images',
quality: 0.8,
});
if (!result.canceled) {
// Handle selected images
console.log('Selected:', result.assets);
}
};import { useMediaLibraryPermissions, useCameraPermissions } from 'expo-image-picker';
function MediaPickerComponent() {
const [libraryStatus, requestLibrary] = useMediaLibraryPermissions();
const [cameraStatus, requestCamera] = useCameraPermissions();
const pickFromLibrary = async () => {
if (!libraryStatus?.granted) {
await requestLibrary();
}
if (libraryStatus?.granted) {
const result = await ImagePicker.launchImageLibraryAsync();
// Handle result
}
};
const takePhoto = async () => {
if (!cameraStatus?.granted) {
await requestCamera();
}
if (cameraStatus?.granted) {
const result = await ImagePicker.launchCameraAsync();
// Handle result
}
};
return (
<div>
<button onClick={pickFromLibrary}>
Choose from Library
</button>
<button onClick={takePhoto}>
Take Photo
</button>
</div>
);
}