Getting pop up 'Allow app to modify this photo ?' when I try to download an image

113 Views Asked by At

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",
1

There are 1 best solutions below

1
On

I had the same problem: You can adjust passing true inside addAssetsToAlbumAsync and createAlbumAsync props:

Example:

if (album === null) {
  await MediaLibrary.createAlbumAsync('Download', asset, true);
} else {
  await MediaLibrary.addAssetsToAlbumAsync([asset], album, true);
}

You can also delete the original file:

if (album === null) {
  await MediaLibrary.createAlbumAsync('Download', asset, true);
  await FileSystem.deleteAsync(fileUri);
} else {
  await MediaLibrary.addAssetsToAlbumAsync([asset], album, true);
  await FileSystem.deleteAsync(fileUri);
}