React Native open failed: ENOENT (No such file or directory) after save image to camera roll

Viewed 742

I want save one of views in my react native app as an image to camera roll. I'm using camera roll to save image. I got alert "Image saved successfully" but at the same time on the screen displayed error: " Possible Unhandled Promise Rejection (id: 2): Error: /cacheDir/rn_image_picker_lib_temp_aefbf48e-3b44-461e-a9ec-d51ce0aefb4c.jpg: open failed: ENOENT (No such file or directory)...".

Below I paste code of my UploadScreen class. The image was saved, but the size of file is equal 0 bytes and I can't open it.

Someone could help me?

Thanks in advance

I added dependecy to Android Manifest:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

This is my imported library:

import React from 'react';
import { Text, TextInput, View, Button, Image, ImageBackground, StyleSheet, Alert, PermissionsAndroid } from 'react-native';
import { createAppContainer, StackNavigator } from 'react-navigation';
import { createDrawerNavigator } from 'react-navigation-drawer';
import { createStackNavigator } from 'react-navigation-stack';
import Icon from 'react-native-vector-icons/FontAwesome';
import DialogAndroid from 'react-native-dialogs';
import Sound from 'react-native-sound';
import * as ImagePicker from 'react-native-image-picker';
import CameraRoll from '@react-native-community/cameraroll';

Upload Screen code:

class UploadScreen extends React.Component {
constructor(props) {
    super(props)
    this.state = {
        filepath: {
            data: '',
            uri: ''
        },
        fileData: '',
        fileUri: ''
    }
}

static navigationOptions = ({ navigation }) => ({
    headerShown: false
});

showContact = () => {
    Sound.setCategory('Playback');

    var mySound = new Sound('sound.mp3', Sound.MAIN_BUNDLE, (error) => {
        if (error) {
            console.log('Blad wczytywania: ' + error);
            return;
        }
        else {
            mySound.play((success) => {
                if (success) {
                    console.log('Odtwarzanie')
                }
            })
        }
    });

    mySound.setVolume(1.0);
    mySound.release();
}

showDescription = () => {
    Sound.setCategory('Playback');

    var mySound = new Sound('sound.mp3', Sound.MAIN_BUNDLE, (error) => {
        if (error) {
            console.log('Blad wczytywania: ' + error);
            return;
        }
        else {
            mySound.play((success) => {
                if (success) {
                    console.log('Odtwarzanie')
                }
            })
        }
    });

    mySound.setVolume(1.0);
    mySound.release();

    Alert.alert('Aplikacja do generowania wlasnych memow', '1. Przeslij swoje zdjecie lub wybierz z jedno z dostepnych. \n 2. Napisz tekst. \n 3. Zapisz utworzony mem. \n\ 4. Udostepnij na swoich social mediach.');
}

selectImage = () => {
    let options = {
        storageOptions: {
            skipBackup: true,
            path: 'images',
        },
    };
    ImagePicker.launchImageLibrary(options, (response) => {
        console.log('Response = ', response);

        if (response.didCancel) {
            console.log('User cancelled image picker');
        } else if (response.error) {
            console.log('ImagePicker Error: ', response.error);
        } else if (response.customButton) {
            console.log('User tapped custom button: ', response.customButton);
            alert(response.customButton);
        } else {
            const source = { uri: response.uri };
            console.log('response', JSON.stringify(response));
            this.setState({
                filePath: response,
                fileData: response.data,
                fileUri: response.uri
            });
        }
    });

}

takePhoto = () => {
    let options = {
        storageOptions: {
            skipBackup: true,
            path: 'images',
        },
    };
    ImagePicker.launchCamera(options, (response) => {
        console.log('Response = ', response);

        if (response.didCancel) {
            console.log('User cancelled image picker');
        } else if (response.error) {
            console.log('ImagePicker Error: ', response.error);
        } else if (response.customButton) {
            console.log('User tapped custom button: ', response.customButton);
            alert(response.customButton);
        } else {
            const source = { uri: response.uri };
            console.log('response', JSON.stringify(response));
            this.setState({
                filePath: response,
                fileData: response.data,
                fileUri: response.uri
            });
        }
    });

}

renderImage() {
    if (this.state.fileUri) {
        return <Image ref="meme" source={{ uri: this.state.fileUri  }} 
            style={{ width: '100%', height: '100%', resizeMode: 'cover' }}
        />
    } else {
        return <Image ref="meme" source={require('./sources/1.jpg')}
            style={{ width: '100%', height: '100%', resizeMode: 'cover' }}
        />
    }
}

state = {
    top: '',
    bottom: '',
};

getPermissionAndroid = async () => {
    try {
        const granted = await PermissionsAndroid.request(
            PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
            {
                title: 'Image Save Permission',
                message: 'Your permission is required to save images to your device',
                buttonNegative: 'Cancel',
                buttonPositive: 'OK',
            },
        );
        if (granted === PermissionsAndroid.RESULTS.GRANTED) {
            return true;
        }
        Alert.alert(
            '',
            'Your permission is required to save images to your device',
            [{ text: 'OK', onPress: () => { } }],
            { cancelable: false },
        );
    } catch (err) {
        console.log('err', err);
    }
};

onSaveImage = async () => {
    try {
        var uri = this.state.fileUri;
        console.log(uri);

        if (Platform.OS === 'android') {
            const granted = this.getPermissionAndroid;
            if (!granted) {
                return;
            }
        }

        const image = CameraRoll.save(uri, 'photo');
        if (image) {
            Alert.alert(
                '',
                'Image saved successfully.',
                [{ text: 'OK', onPress: () => { } }],
                { cancelable: false },
            );
        }
    } catch (error) {
        console.log('error', error);
    }
};

render() {
    const { navigate } = this.props.navigation;
    const { top, bottom } = this.state;

    return (
        <View
            style={{
                flex: 1,
            }}>
            <ImageBackground style={styles.imgBackground}
                resizeMode='cover'
                source={require('./sources/background.jpg')}>
                <View
                    style={{
                        flex: 1,
                        flexDirection: 'row',
                        justifyContent: 'space-between',
                        alignItems: 'flex-end',
                    }}>
                    <Icon.Button style={{ right: -4 }}
                        name="info-circle"
                        onPress={this.showDescription} >
                    </Icon.Button>
                    <Icon.Button style={{ right: -4 }}
                        name="home"
                        onPress={() => navigate('Home')}
                    >
                    </Icon.Button>
                    <Icon.Button style={{ right: -6 }}
                        name="at"
                        onPress={this.showContact}
                    >
                    </Icon.Button>
                </View>
                <View style={{ flex: 2, alignItems: 'center', justifyContent: 'space-between', }}>
                    <TextInput underlineColorAndroid={'transparent'} style={styles.input} value={top} onChangeText={(top) => this.setState({ top })} placeholder={'Input top text here'} />
                    <TextInput underlineColorAndroid={'transparent'} style={styles.input} value={bottom} onChangeText={(bottom) => this.setState({ bottom })} placeholder={'Input bottom text here'} />
                </View>
                <View style={{ flex: 5, alignItems: 'center', justifyContent: 'space-between', }}>
                    {this.renderImage()}
                    <Text style={ styles.memeTop }>{top}</Text>
                    <Text style={styles.memeBottom}>{bottom}</Text>
                </View>
                <View style={{ flex: 2, alignItems: 'center', justifyContent: 'space-between', margin: 5}}>
                    <Button title="Select image file"
                        onPress={this.selectImage}
                    />
                    <Button title="Take a photo"
                        onPress={this.takePhoto}
                    />
                    <Button title="Save result"
                        //onPress={() => navigate('Result')}
                        onPress={this.onSaveImage}
                    />
                </View >
                <View style={{ flex: 0.3 }}>
                    <Text style={{
                        fontFamily: 'Impact', fontWeight: 'bold', fontSize: 10, textAlign: 'right', alignSelf: 'flex-end',
                        textShadowColor: 'black', textShadowOffset: { width: 10, height: 5 }, textShadowRadius: 10,
                        color: 'white', position: 'absolute', bottom: 0
                    }}>
                        Copyright all right reserved {'\u00A9'} 2021 Marek Przybylowski
                    </Text>
                </View >
            </ImageBackground>
        </View>
    );
}
}
0 Answers
Related