Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native saveToCameraRoll failed with `Permission denied` error on Android

Description

saveToCameraRoll failed with Permission denied error on Android

Reproduction

Saving a AWS S3 photo to the device Camera Roll suddenly failed

RNFS.downloadFile(DownloadFileOptions)
            .promise
            .then(() => {
                 CameraRoll.saveToCameraRoll(path, this.state.type) // path = /data/user/0/com.XXX.app/filesimage-xyz.jpg"
                    .then((data) => {
                        RNFS.unlink(path)
                            .then(() => {
                                console.log('Download and file unlink succeeded');
                            })
                            .catch((err) => {
                                console.error("RNFS unlink error: ", err.message);
                            });
                        })
                    .catch((error) => { 
                        console.error("Save to Cameral roll  error: ",error.message); 
//error = code:"EUNSPECIFIED"
// framesToPop:1
// message:"Permission denied"
// stack:"Error: Permission denied↵  
                    });
                })
            .catch((error) => {
                console.error("RNFS.downloadFile! error: ", error.message);
            });

In the android/app/src/main/AndroidManifest.xml i have <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> among few other permissions.

What can cause a permission denied error ? what shall be done at the Manifest level to save to cameraRoll ?

Additional Information

  • React Native version: [FILL THIS OUT: Does the bug reproduce on the latest RN release?] Check with V41
  • Platform: [FILL THIS OUT: iOS, Android, or both?] Android inly
  • Operating System: [FILL THIS OUT: MacOS, Linux, or Windows?] Dev MacOS Sierra
  • Dev tools: [FILL THIS OUT: Xcode or Android Studio version, iOS or Android SDK version, if applicable] RN CLI + Android SDK
like image 632
Philippe Cohen Avatar asked Mar 14 '17 22:03

Philippe Cohen


2 Answers

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. You can use PermissionAndroid API to let users to grant permission for external storage access.

Example:

  requestExternalStoragePermission = async () => {
    try {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
        {
          title: 'My App Storage Permission',
          message: 'My App needs access to your storage ' +
            'so you can save your photos',
        },
      );
      return granted;
    } catch (err) {
      console.error('Failed to request permission ', err);
      return null;
    }
  };
like image 89
alpha Avatar answered Nov 01 '22 11:11

alpha


You can try:

...
let permission = await Expo.Permissions.askAsync(Expo.Permissions.CAMERA_ROLL);

if (permission.status === 'granted') {
   await CameraRoll.saveToCameraRoll(fileUrl, "photo");
}
like image 2
rodrix Avatar answered Nov 01 '22 12:11

rodrix