Working with Camera and Media Capture
1. Setting Up Camera Permissions
| Permission | Description | Android Manifest | iOS Info.plist |
|---|---|---|---|
| CAMERA | Allows access to the device camera for capturing photos and videos. | <uses-permission android:name="android.permission.CAMERA" /> |
<key>NSCameraUsageDescription</key><string>This app uses the camera to capture photos and videos.</string> |
| RECORD_AUDIO | Allows recording audio during video capture. | <uses-permission android:name="android.permission.RECORD_AUDIO" /> |
<key>NSMicrophoneUsageDescription</key><string>This app records audio during video capture.</string> |
| READ_EXTERNAL_STORAGE | Required for reading media files from external storage (e.g., saved photos/videos). | <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
Not required for iOS |
Example: Requesting Camera Permissions in React Native
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);
}
} else {
// iOS logic here
const result = await request(PERMISSIONS.IOS.CAMERA);
console.log('iOS Camera Permission Result:', result);
}
};
Note: On iOS, you must also add the
NSCameraUsageDescription key to your app's Info.plist file.
Warning: On Android 6.0 (API level 23) and above, runtime permissions are required. Permissions must be requested at runtime before accessing camera features.
2. Capturing Photos
| Property | Description | Default |
|---|---|---|
| cameraType | Specifies the camera to use (back or front) | "back" |
| quality | Image quality setting (0-1) | 0.8 |
| mediaType | Media type to capture (photo or video) | "photo" |
Example: Capture Photo
import { Camera } from 'react-native-camera';
<Camera
style={{ flex: 1 }}
type={Camera.Constants.Type.back}
captureQuality={Camera.Constants.Quality.high}
mediaType={Camera.Constants.MediaType.photo}
onPictureSaved={(data) => {
console.log("Photo saved:", data);
}}
/>
Note: Permissions must be requested before capturing photos.
Warning: Ensure camera permissions are granted for both front and back cameras.
3. Recording Videos
| Property | Description | Default | Notes |
|---|---|---|---|
| videoSource | Specifies the camera to use for video recording | "back" |
Can be "front" or "back" |
| quality | Video quality setting | "medium" |
Options: "low", "medium", "high", "ultra" |
| maxDuration | Maximum duration of the video in seconds | 30 |
Set to 0 for unlimited duration |
| recordAudio | Whether to record audio along with video | true |
Set to false to record only video |
Example: Start Video Recording
import { Camera } from 'react-native-camera';
const startRecording = async () => {
try {
const options = {
videoSource: 'back',
quality: 'medium',
maxDuration: 30,
recordAudio: true
};
const data = await Camera.startVideoRecording(options);
console.log('Video recorded:', data.uri);
} catch (error) {
console.error('Error starting video recording:', error);
}
};
Example: Stop Video Recording
import { Camera } from 'react-native-camera';
const stopRecording = async () => {
try {
const data = await Camera.stopVideoRecording();
console.log('Video recorded:', data.uri);
} catch (error) {
console.error('Error stopping video recording:', error);
}
};
Note: Ensure that you have appropriate permissions for camera and audio access before attempting to record videos.
Warning: Video recording may consume significant storage space and battery life. Always consider the user's device limitations.
4. Implementing Camera Controls
| Control | Description | Usage |
|---|---|---|
| cameraType | Specifies the camera to use (front or back) | cameraType: 'back' |
| flashMode | Controls the flash mode (off, on, auto) | flashMode: 'auto' |
| zoom | Adjusts the zoom level (0.0 - 2.0) | zoom: 1.0 |
| focusMode | Sets the focus mode (auto, manual) | focusMode: 'auto' |
Example: Camera Control Configuration
import { Camera } from 'react-native-camera';
<Camera
style={{ flex: 1 }}
type={Camera.Constants.Type.back}
flashMode={Camera.Constants.FlashMode.auto}
zoom={1.0}
focusMode={Camera.Constants.FocusMode.auto}
/>
Note: Ensure camera permissions are requested before using camera controls.
Warning: Zoom levels may vary depending on device capabilities.
5. Accessing Front and Back Camera
| Property | Description | Values |
|---|---|---|
| cameraType | Specifies which camera to use | "front" or "back" |
| permission | Permission status for camera access | "granted", "denied", "undetermined" |
Example: Setting Camera Type
import { Camera } from 'react-native-camera';
const cameraOptions = {
cameraType: 'front',
permission: 'granted'
};
<Camera
type={cameraOptions.cameraType}
captureMode={'still'}
permission={cameraOptions.permission}
/>
Note: Ensure camera permissions are requested before accessing the camera.
Warning: Using
cameraType with unsupported devices may cause runtime errors.
6. Handling Camera Orientation
| Property | Description | Values |
|---|---|---|
| orientation | Specifies the camera orientation | portrait, portrait-upside-down, landscape-left, landscape-right |
| autoRotate | Enables automatic rotation based on device orientation | true, false |
Example: Setting Camera Orientation
import { Camera } from 'react-native-camera';
<Camera
style={styles.camera}
orientation="landscape-left"
autoRotate={true}
/>
Note: The
orientation property may not work as expected on all devices due to hardware limitations.
7. Implementing QR Code Scanning
Example: Basic QR Code Scanner Setup
import React, { useState } from 'react';
import { BarCodeScanner } from 'expo-barcode-scanner';
const QRScanner = () => {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
React.useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ data }) => {
setScanned(true);
alert(`QR Code scanned: ${data}`);
};
if (hasPermission === null) {
return <div>Requesting camera permission</div>;
}
if (hasPermission === false) {
return <div>Camera permission denied</div>;
}
return (
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{ flex: 1 }}
/>
);
};
export default QRScanner;
| Property | Description | Values |
|---|---|---|
| onBarCodeScanned | Callback function when a barcode is scanned | function |
| scanning | Controls whether scanning is active | true or false |
| barCodeTypes | Array of barcode types to scan | ["qr", "ean13"] |
Note: Requires
expo-barcode-scanner package for full QR scanning capabilities.
Warning: Camera permission must be requested and granted before scanning.
QR Code Scanning Workflow
- Request camera permissions using
BarCodeScanner.requestPermissionsAsync() - Set up a scanner component with
BarCodeScannerfromexpo-barcode-scanner - Implement
onBarCodeScannedhandler to process scanned data - Handle permission denial gracefully
8. Using Camera Preview Customization
Example: Basic Camera Preview Setup
import React, { useRef } from 'react';
import { CameraView, CameraProps } from 'expo-camera';
const CameraPreview = () => {
const cameraRef = useRef<CameraView>(null);
return (
<CameraView
ref={cameraRef}
style={{ flex: 1 }}
facing="back"
mode="preview"
/>
);
};
export default CameraPreview;
| Property | Description | Values | Notes |
|---|---|---|---|
| facing | Camera position | "back", "front" |
Default: "back" |
| mode | Camera mode | "preview", "still", "video" |
For preview, use "preview" |
| zoom | Zoom level | 0.0 - 1.0 |
Default: 0.0 (no zoom) |
| flashMode | Flash mode | "off", "on", "auto" |
Default: "off" |
| exposureMode | Exposure mode | "auto", "locked" |
Default: "auto" |
Note: Camera preview customization is supported in Expo SDK 51+.
Example: Customizing Camera Preview with Zoom and Flash
import React, { useRef } from 'react';
import { CameraView, CameraProps } from 'expo-camera';
const CustomCameraPreview = () => {
const cameraRef = useRef<CameraView>(null);
return (
<CameraView
ref={cameraRef}
style={{ flex: 1 }}
facing="back"
mode="preview"
zoom={0.5}
flashMode="auto"
/>
);
};
export default CustomCameraPreview;
9. Handling Camera Errors
| Error Type | Description | Handling Strategy |
|---|---|---|
| CameraNotAuthorized | Permission not granted to access camera | Redirect user to app settings or show a modal explaining the need for permission |
| CameraNotAvailable | Camera hardware is not available (e.g., device has no camera) | Fallback to media library or display an error message |
| CameraUnavailable | Camera is currently in use by another app | Display a message to the user and retry after a delay |
| MediaRecorderError | Failure during media recording (e.g., disk full, unsupported format) | Log error and provide user feedback; attempt to recover or stop recording |
Example: Error Handling in Camera Capture
import { Camera } from 'react-native-camera';
const captureImage = async () => {
try {
const options = { quality: 0.5, width: 640 };
const data = await Camera.capture(options);
console.log('Image captured:', data);
} catch (error) {
if (error.code === 'CAMERA_NOT_AUTHORIZED') {
Alert.alert(
'Permission Required',
'Camera access is needed to capture images. Please enable in Settings.'
);
} else if (error.code === 'MEDIA_RECORDER_ERROR') {
Alert.alert('Recording Error', 'Failed to record media. Please try again.');
} else {
console.error('Camera error:', error);
}
}
};
Note: Always handle camera errors gracefully to provide a better user experience and avoid app crashes.
10. Using react-native-vision-camera
Example: Basic Camera Setup
import { Camera } from 'react-native-vision-camera';
function CameraScreen() {
const camera = Camera.useCameraDevice('back');
return (
<Camera
style={{ flex: 1 }}
device={camera}
isActive={true}
/>
);
}
| Property | Description | Default | Notes |
|---|---|---|---|
| device | Camera device to use (e.g., 'back', 'front') | undefined | Required |
| isActive | Whether camera is active | false | Boolean |
| photo | Photo capture options | null | Object with photo settings |
| video | Video capture options | null | Object with video settings |
Note: Make sure to add camera permissions in your app's manifest or info.plist.
Warning: Camera access requires runtime permissions on Android and iOS.