Search code examples
javascriptimagereact-nativeexpomedia-library

How do I save an image to Media Library in React Native Expo


I'm trying to let the user download an image on long press, after searching in the Expo documents I've been able to find some methods, but I'm not sure why it's not working!

Here's my code:

import React from 'react'
import { Image } from 'react-native-elements'
import { ActivityIndicator, StyleSheet, View, TouchableOpacity } from 'react-native'
import * as MediaLibrary from 'expo-media-library';
import * as Permissions from 'expo-permissions';

const Img = () => {

  const download = async (uri) => {
    const { status } = await Permissions.askAsync(Permissions.MEDIA_LIBRARY);

    if (status === 'granted') {
      let uriString = uri.toString();
      const asset = MediaLibrary.createAssetAsync(uriString);
      await MediaLibrary.createAlbumAsync("DownLoads", asset);
    }
  }

  return (
    <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
      <TouchableOpacity activeOpacity={0.2}>
        <Image source={{ uri: "https://miro.medium.com/max/1838/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg" }}
        style={{ width: 300, height: 300 }}
        onLongPress={download(Image.uri)}
        PlaceholderContent={<ActivityIndicator />} />
      </TouchableOpacity>
    </View>
  )
}

export default Img

const styles = StyleSheet.create({})

am I missing something?


Solution

  • This is old but... createAssetAsync is a method to invoke on local files. It's a way of organizing media.

    const asset = MediaLibrary.createAssetAsync(uriString);
    

    MediaLibrary.createAssetAsync(localUri) - localUri (string) - A URI to the image or video file. It must contain an extension. On Android it must be a local path, so it must start with file:///.

    You have to download it first with FileSystem.downloadAsync to FileSystem.documentDirectory.

    const localuri = await FileSystem.downloadAsync(uri, FileSystem.documentDirectory + filename)
    const asset = await MediaLibrary.createAssetAsync(localuri)
    const album = await MediaLibrary.createAlbumAsync("DownLoads", asset);