Media and File Handling
Image Processing and Display
Basic Image Component
import React from 'react';
import { View, Image, StyleSheet } from 'react-native';
const ImageExample = () => {
return (
<View style={styles.container}>
{/* Network image */}
<Image
source={{ uri: 'https://example.com/image.jpg' }}
style={styles.image}
resizeMode="cover" // Image scaling mode: cover, contain, stretch, repeat, center
/>
{/* Local static image (requires proper configuration in Xcode/Android Studio) */}
<Image
source={require('./assets/local-image.png')}
style={styles.image}
/>
{/* Dynamic local image reference (using a workaround for require) */}
<Image
source={getImageSource('dynamic-image')} // Custom function below
style={styles.image}
/>
</View>
);
};
// Workaround for dynamically referencing local images (since require doesn't support variable paths)
const imageMap = {
'dynamic-image': require('./assets/dynamic-image.png'),
'another-image': require('./assets/another-image.png'),
};
const getImageSource = (imageName) => imageMap[imageName] || require('./assets/fallback-image.png');
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
padding: 10,
},
image: {
width: 150,
height: 150,
margin: 5,
},
});
export default ImageExample;
Image Caching and Performance Optimization
import React, { useState } from 'react';
import { View, Image, ActivityIndicator, StyleSheet } from 'react-native';
import FastImage from 'react-native-fast-image'; // Third-party high-performance image library
const CachedImageExample = () => {
const [loading, setLoading] = useState(true);
return (
<View style={styles.container}>
{/* Using FastImage for image caching */}
<FastImage
style={styles.image}
source={{
uri: 'https://example.com/large-image.jpg',
priority: FastImage.priority.high, // Loading priority
cache: FastImage.cacheControl.immutable, // Cache strategy
}}
resizeMode={FastImage.resizeMode.cover}
onLoadStart={() => setLoading(true)}
onLoadEnd={() => setLoading(false)}
/>
{/* Loading indicator */}
{loading && (
<ActivityIndicator
style={styles.loader}
size="large"
color="#0000ff"
/>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
image: {
width: 300,
height: 200,
},
loader: {
position: 'absolute',
},
});
export default CachedImageExample;
Audio and Video Processing
Audio Playback Implementation
import React, { useState, useEffect, useRef } from 'react';
import { View, Button, Text, StyleSheet } from 'react-native';
import Sound from 'react-native-sound'; // Third-party audio library
const AudioPlayerExample = () => {
const [isPlaying, setIsPlaying] = useState(false);
const [duration, setDuration] = useState(0);
const [currentTime, setCurrentTime] = useState(0);
const soundRef = useRef(null);
useEffect(() => {
// Initialize audio
soundRef.current = new Sound('https://example.com/audio.mp3', '', (error) => {
if (error) {
console.log('Failed to load the sound', error);
return;
}
// Get audio duration
setDuration(soundRef.current.getDuration());
});
// Clean up resources on component unmount
return () => {
if (soundRef.current) {
soundRef.current.release();
}
};
}, []);
const togglePlayPause = () => {
if (isPlaying) {
soundRef.current.pause();
} else {
soundRef.current.play((success) => {
if (success) {
console.log('Audio played successfully');
} else {
console.log('Audio playback failed');
}
});
}
setIsPlaying(!isPlaying);
};
const formatTime = (seconds) => {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
};
return (
<View style={styles.container}>
<Button
title={isPlaying ? 'Pause' : 'Play'}
onPress={togglePlayPause}
/>
<Text>Duration: {formatTime(duration)}</Text>
<Text>Current Time: {formatTime(currentTime)}</Text>
{/* Progress bar (simplified) */}
<View style={styles.progressBar}>
<View
style={[
styles.progressFill,
{ width: `${(currentTime / duration) * 100}%` },
]}
/>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
progressBar: {
height: 10,
width: '100%',
backgroundColor: '#e0e0e0',
borderRadius: 5,
marginTop: 20,
},
progressFill: {
height: '100%',
backgroundColor: '#2196f3',
borderRadius: 5,
},
});
export default AudioPlayerExample;
Video Playback Implementation
import React, { useState, useRef } from 'react';
import { View, Button, Text, StyleSheet } from 'react-native';
import Video from 'react-native-video'; // Third-party video library
const VideoPlayerExample = () => {
const [isPlaying, setIsPlaying] = useState(false);
const [currentTime, setCurrentTime] = useState(0);
const [duration, setDuration] = useState(0);
const videoRef = useRef(null);
const togglePlayPause = () => {
setIsPlaying(!isPlaying);
};
const handleProgress = (data) => {
setCurrentTime(data.currentTime);
};
const handleLoad = (data) => {
setDuration(data.duration);
};
const formatTime = (seconds) => {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
};
return (
<View style={styles.container}>
<Video
ref={videoRef}
source={{ uri: 'https://example.com/video.mp4' }}
style={styles.video}
paused={!isPlaying}
onProgress={handleProgress}
onLoad={handleLoad}
resizeMode="contain"
controls={false} // Hide default controls, use custom controls
/>
<View style={styles.controls}>
<Button
title={isPlaying ? 'Pause' : 'Play'}
onPress={togglePlayPause}
/>
<Text style={styles.timeText}>
{formatTime(currentTime)} / {formatTime(duration)}
</Text>
{/* Simplified progress bar */}
<View style={styles.progressBar}>
<View
style={[
styles.progressFill,
{ width: `${(currentTime / duration) * 100}%` },
]}
/>
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#000',
},
video: {
width: '100%',
height: 300,
},
controls: {
padding: 10,
alignItems: 'center',
},
timeText: {
color: '#fff',
marginVertical: 5,
},
progressBar: {
height: 10,
width: '100%',
backgroundColor: '#444',
borderRadius: 5,
marginTop: 5,
},
progressFill: {
height: '100%',
backgroundColor: '#2196f3',
borderRadius: 5,
},
});
export default VideoPlayerExample;
File System Operations
File Reading and Writing Implementation
import React, { useState } from 'react';
import { View, Button, TextInput, Text, StyleSheet, Alert } from 'react-native';
import RNFS from 'react-native-fs'; // Third-party file system library
const FileSystemExample = () => {
const [text, setText] = useState('');
const [fileContent, setFileContent] = useState('');
// Document directory path
const documentDir = RNFS.DocumentDirectoryPath;
// Create file path
const filePath = `${documentDir}/example.txt`;
// Write file
const writeFile = async () => {
try {
// Write text to file
await RNFS.writeFile(filePath, text, 'utf8');
Alert.alert('Success', 'File written successfully');
} catch (error) {
console.error('Error writing file', error);
Alert.alert('Error', 'Failed to write file');
}
};
// Read file
const readFile = async () => {
try {
// Check if file exists
const exists = await RNFS.exists(filePath);
if (!exists) {
Alert.alert('Error', 'File does not exist');
return;
}
// Read file content
const content = await RNFS.readFile(filePath, 'utf8');
setFileContent(content);
} catch (error) {
console.error('Error reading file', error);
Alert.alert('Error', 'Failed to read file');
}
};
// Delete file
const deleteFile = async () => {
try {
// Check if file exists
const exists = await RNFS.exists(filePath);
if (!exists) {
Alert.alert('Error', 'File does not exist');
return;
}
// Delete file
await RNFS.unlink(filePath);
setFileContent('');
Alert.alert('Success', 'File deleted successfully');
} catch (error) {
console.error('Error deleting file', error);
Alert.alert('Error', 'Failed to delete file');
}
};
return (
<View style={styles.container}>
<TextInput
style={styles.textInput}
multiline
numberOfLines={4}
value={text}
onChangeText={setText}
placeholder="Enter text to save"
/>
<View style={styles.buttonContainer}>
<Button title="Write File" onPress={writeFile} />
<Button title="Read File" onPress={readFile} />
<Button title="Delete File" onPress={deleteFile} />
</View>
<Text style={styles.contentTitle}>File Content:</Text>
<Text style={styles.contentText}>{fileContent}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
textInput: {
height: 100,
borderColor: '#ccc',
borderWidth: 1,
padding: 10,
marginBottom: 20,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 20,
},
contentTitle: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 5,
},
contentText: {
borderWidth: 1,
borderColor: '#ccc',
padding: 10,
height: 100,
},
});
export default FileSystemExample;
File Download and Management
import React, { useState, useRef } from 'react';
import { View, Button, Text, StyleSheet } from 'react-native';
import RNFS from 'react-native-fs';
import { Alert } from 'react-native';
const FileDownloadExample = () => {
const [downloadProgress, setDownloadProgress] = useState(0);
const [isDownloading, setIsDownloading] = useState(false);
const downloadTaskRef = useRef(null);
// Download file
const startDownload = async () => {
if (isDownloading) return;
const downloadDest = `${RNFS.DocumentDirectoryPath}/downloaded_file.pdf`;
const options = {
fromUrl: 'https://example.com/sample.pdf',
toFile: downloadDest,
background: true,
begin: (res) => {
console.log('Download started', res);
},
progress: (res) => {
const progress = (res.bytesWritten / res.contentLength) * 100;
setDownloadProgress(progress);
console.log('Download progress:', progress);
},
};
try {
setIsDownloading(true);
downloadTaskRef.current = RNFS.downloadFile(options);
await downloadTaskRef.current.promise;
Alert.alert('Success', 'File downloaded successfully');
} catch (error) {
console.error('Error downloading file', error);
Alert.alert('Error', 'Failed to download file');
} finally {
setIsDownloading(false);
setDownloadProgress(0);
}
};
// Cancel download
const cancelDownload = () => {
if (downloadTaskRef.current) {
downloadTaskRef.current.cancel();
setIsDownloading(false);
setDownloadProgress(0);
}
};
return (
<View style={styles.container}>
<Button
title={isDownloading ? 'Cancel Download' : 'Download File'}
onPress={isDownloading ? cancelDownload : startDownload}
/>
{isDownloading && (
<View style={styles.progressContainer}>
<Text>Download Progress: {downloadProgress.toFixed(2)}%</Text>
{/* Progress bar (simplified) */}
<View style={styles.progressBar}>
<View
style={[
styles.progressFill,
{ width: `${downloadProgress}%` },
]}
/>
</View>
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
progressContainer: {
marginTop: 20,
},
progressBar: {
height: 10,
width: '100%',
backgroundColor: '#e0e0e0',
borderRadius: 5,
marginTop: 5,
},
progressFill: {
height: '100%',
backgroundColor: '#2196f3',
borderRadius: 5,
},
});
export default FileDownloadExample;
Camera and Gallery Integration
Camera Functionality Implementation
import React, { useState, useEffect } from 'react';
import { View, Button, Image, StyleSheet, Alert } from 'react-native';
import { Camera } from 'react-native-camera'; // Third-party camera library
const CameraExample = () => {
const [cameraRef, setCameraRef] = useState(null);
const [photo, setPhoto] = useState(null);
const [isCameraReady, setIsCameraReady] = useState(false);
// Request camera permission
useEffect(() => {
(async () => {
const granted = await Camera.requestCameraPermission();
if (!granted) {
Alert.alert('Permission required', 'Camera permission is required to use this feature');
}
})();
}, []);
// Take picture
const takePicture = async () => {
if (cameraRef && isCameraReady) {
try {
const options = { quality: 0.5, base64: true };
const data = await cameraRef.takePictureAsync(options);
setPhoto(data.uri);
} catch (error) {
console.error('Error taking picture', error);
Alert.alert('Error', 'Failed to take picture');
}
}
};
return (
<View style={styles.container}>
{!photo ? (
<Camera
ref={ref => setCameraRef(ref)}
style={styles.camera}
type={Camera.Constants.Type.back}
onCameraReady={() => setIsCameraReady(true)}
>
<View style={styles.buttonContainer}>
<Button title="Take Picture" onPress={takePicture} />
</View>
</Camera>
) : (
<View style={styles.previewContainer}>
<Image source={{ uri: photo }} style={styles.previewImage} />
<Button title="Retake" onPress={() => setPhoto(null)} />
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
backgroundColor: 'transparent',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'flex-end',
marginBottom: 20,
},
previewContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
previewImage: {
width: '100%',
height: '100%',
resizeMode: 'contain',
},
});
export default CameraExample;
Gallery Access Implementation
import React, { useState } from 'react';
import { View, Button, Image, StyleSheet, Alert } from 'react-native';
import * as ImagePicker from 'react-native-image-picker'; // Third-party gallery library
const ImagePickerExample = () => {
const [image, setImage] = useState(null);
const pickImage = () => {
const options = {
mediaType: 'photo',
includeBase64: false,
maxHeight: 2000,
maxWidth: 2000,
};
ImagePicker.launchImageLibrary(options, (response) => {
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
Alert.alert('Error', 'Failed to pick image');
} else {
setImage(response.uri);
}
});
};
return (
<View style={styles.container}>
{!image ? (
<Button title="Pick an image from gallery" onPress={pickImage} />
) : (
<View style={styles.imageContainer}>
<Image source={{ uri: image }} style={styles.image} />
<Button title="Pick another image" onPress={() => setImage(null)} />
</View>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
imageContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
image: {
width: '100%',
height: 300,
resizeMode: 'contain',
},
});
export default ImagePickerExample;
File Sharing and Exporting
File Sharing Implementation
import React, { useState } from 'react';
import { View, Button, Text, StyleSheet, Alert } from 'react-native';
import RNFS from 'react-native-fs';
import Share from 'react-native-share'; // Third-party sharing library
const FileShareExample = () => {
const [shared, setShared] = useState(false);
const documentDir = RNFS.DocumentDirectoryPath;
const filePath = `${documentDir}/example.txt`;
// Create example file
const createExampleFile = async () => {
try {
await RNFS.writeFile(filePath, 'This is an example file content', 'utf8');
Alert.alert('Success', 'Example file created');
} catch (error) {
console.error('Error creating file', error);
Alert.alert('Error', 'Failed to create file');
}
};
// Share file
const shareFile = async () => {
try {
// Check if file exists
const exists = await RNFS.exists(filePath);
if (!exists) {
await createExampleFile();
}
// Configure sharing options
const options = {
url: `file://${filePath}`,
message: 'Check out this file!',
type: 'application/octet-stream', // Generic file type
};
// Perform sharing
await Share.open(options);
setShared(true);
} catch (error) {
console.error('Error sharing file', error);
Alert.alert('Error', 'Failed to share file');
}
};
return (
<View style={styles.container}>
<Button title="Create Example File" onPress={createExampleFile} />
<Button title="Share File" onPress={shareFile} />
{shared && <Text style={styles.successText}>File shared successfully!</Text>}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
successText: {
marginTop: 20,
color: 'green',
fontWeight: 'bold',
},
});
export default FileShareExample;
File Export to Other Applications
import React, { useState } from 'react';
import { View, Button, Text, StyleSheet, Alert } from 'react-native';
import RNFS from 'react-native-fs';
import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker'; // Third-party document picker library
const FileExportExample = () => {
const [exported, setExported] = useState(false);
const documentDir = RNFS.DocumentDirectoryPath;
const filePath = `${documentDir}/exported_file.txt`;
// Create file to export
const createExportFile = async () => {
try {
await RNFS.writeFile(filePath, 'This is the content to export', 'utf8');
Alert.alert('Success', 'File created for export');
} catch (error) {
console.error('Error creating export file', error);
Alert.alert('Error', 'Failed to create export file');
}
};
// Export file to other applications
const exportFile = async () => {
try {
// Check if file exists
const exists = await RNFS.exists(filePath);
if (!exists) {
await createExportFile();
}
// Configure document picker options
const options = {
type: [DocumentPickerUtil.allFiles()], // All file types
};
// Open document picker for export
const result = await DocumentPicker.show(options);
if (result && result[0]) {
// Implementation for copying file to selected location would be more complex
// Requires native modules or platform-specific APIs
console.log('File export path:', result[0].uri);
// Simplified example: Show success message
setExported(true);
Alert.alert('Success', 'File export initiated');
}
} catch (error) {
console.error('Error exporting file', error);
Alert.alert('Error', 'Failed to export file');
}
};
return (
<View style={styles.container}>
<Button title="Create Export File" onPress={createExportFile} />
<Button title="Export File" onPress={exportFile} />
{exported && <Text style={styles.successText}>File export initiated!</Text>}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
successText: {
marginTop: 20,
color: 'green',
fontWeight: 'bold',
},
});
export default FileExportExample;
Summary of Media and File Handling
React Native provides various methods for handling media and files, from simple image display to complex file system operations. Developers can choose the appropriate solution based on their needs:
- Image Processing:
- Use the
Imagecomponent to display network and local images. - Use
react-native-fast-imagefor high-performance image caching. - Handle limitations and workarounds for dynamically loading local images.
- Use the
- Audio and Video:
- Use
react-native-soundfor audio playback. - Use
react-native-videofor video playback functionality. - Consider custom controls for a better user experience.
- Use
- File System:
- Use
react-native-fsfor file reading, writing, downloading, and management. - Pay attention to file permissions and platform differences.
- Implement progress feedback to enhance user experience.
- Use
- Camera and Gallery:
- Use
react-native-camerato access the device camera. - Use
react-native-image-pickerto select images from the gallery. - Handle permission requests and error cases.
- Use
- File Sharing and Exporting:
- Use
react-native-sharefor file sharing. - Consider platform-specific export methods.
- Provide clear user feedback.
- Use
Best practices include:
- Always handle permission requests and error cases.
- Provide operation feedback (e.g., progress bars, loading indicators).
- Manage memory for large file operations.
- Follow platform-specific design guidelines.
- Test on different devices and operating system versions.
By effectively combining these techniques, developers can build feature-rich, user-friendly media and file handling functionalities.



