I am developing React Native Expo application that displays a list of images and and allows user to download these images to their device (specifically download folder). It uses two main expo libraries: expo-media-library and expo-file-system.
The problem i am facing in the application is that whenever a user tries to download an image, an alert pops up asking for permission saying "Allow app to modify this photo ?" This alert appears each time an image is downloaded the alert popup, creating an interruption and seeking permission before every download action. There are 2 options. Allow and Deny. If I click 'allow', the image is downloaded to the downloads folder else if I tap 'deny', the application crashes and the image is still downloaded to the same folder.
Is there a way to download image without the pop up ? Appreciate the help.
Below is code snippet from my project.
I also have a expo snack where the issue can be duplicated. Link = https://snack.expo.dev/@balan12/adequate-orange-popcorn
import React, { useEffect } from 'react';
import { SafeAreaView, StyleSheet, Image, TouchableOpacity, Alert,Text } from 'react-native';
import * as MediaLibrary from 'expo-media-library';
import * as FileSystem from 'expo-file-system';
const pictureArray = [
{ url: 'https://i.pinimg.com/originals/cf/5d/f7/cf5df7e4e7804644a43be3f66a224b9d.jpg', title: 'Image1.jpg' },
{ url: 'https://img.freepik.com/free-photo/painting-mountain-lake-with-mountain-background_188544-9126.jpg?size=626&ext=jpg&ga=GA1.1.1412446893.1704326400&semt=sph', title: 'Image2.jpg' },
{ url: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR7BuBOOTa_XglTuj2GTZxxffYST85b65PR2uRo-4n95w&s', title: 'Image3.jpg' },
];
const downloadPictureToLocalStorage = async (imageUrl, title) => {
try {
const fileUri = FileSystem.documentDirectory + title;
const downloadObject = FileSystem.createDownloadResumable(imageUrl, fileUri);
const { uri } = await downloadObject.downloadAsync();
const asset = await MediaLibrary.createAssetAsync(uri);
const album = await MediaLibrary.getAlbumAsync('Download');
if (album === null) {
await MediaLibrary.createAlbumAsync('Download', asset, false);
} else {
await MediaLibrary.addAssetsToAlbumAsync([asset], album, false);
}
console.log('Attachment downloaded and saved successfully!');
} catch (err) {
console.log('Error downloading image:', err);
}
};
const App = () => {
useEffect(() => {
(async () => {
const { status } = await MediaLibrary.requestPermissionsAsync();
if (status !== "granted") {
console.log("MEDIA_LIBRARY permission not granted!");
} else {
console.log("MEDIA_LIBRARY permission granted!");
}
})();
}, []);
const handleImagePress = async (imageUrl, title) => {
await downloadPictureToLocalStorage(imageUrl, title);
};
return (
<SafeAreaView style={styles.container}>
<Text>hello</Text>
{pictureArray.map((item, index) => (
<TouchableOpacity key={index} onPress={() => handleImagePress(item.url, item.title)}>
<Image source={{ uri: item.url }} style={styles.image} />
</TouchableOpacity>
))}
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
backgroundColor: '#ecf0f1',
paddingTop: 200,
},
image: {
width: 200,
height: 200,
marginBottom: 20,
},
});
export default App;
Package Versions i have used in this Project:
"expo": "^49.0.13",
"react-native": "0.72.6",
"expo-file-system": "~15.4.4",
"expo-media-library": "~15.4.1",
I had the same problem: You can adjust passing
true
insideaddAssetsToAlbumAsync
andcreateAlbumAsync
props:Example:
You can also delete the original file: