Provides access to the system's UI for selecting images and videos from the phone's library or taking a photo with the camera.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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>
);
}