Ron Astle Lobo
Ron Astle Lobo

Reputation: 1314

How to get Absolute path of a file in react-native?

I am looking for a file picker in react-native which returns me Absolute Path of the file picked. I am currently using react-native-document-picker, but it gives me the relative path in the format of content://com.android.providers.media.documents/document/....... As I want to compress my video file, libraries like react-native-ffmpeg and react-native-video-processing require Absolute path of a file.

Upvotes: 14

Views: 40101

Answers (5)

Matt
Matt

Reputation: 344

First you have to ask for Android Permissions so make sure you call this function first:

    export const requestReadExternalStorage = () => {
      PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
    };

After you call this function and Permissions are accepted you can pass the uri to this function:

    export const getPath = (uri: string) => {
      if (uri.startsWith('content://')) {
        return RNFetchBlob.fs.stat(uri).then(info => info?.path);
      }
      return uri;
    };

Then you just need to call it and use the real uri now, like this:

    // res?.uri is the uri returned from the DocumentPicker.pick() response.
    const uri = await getPath(res?.uri);

Upvotes: 3

jay ram
jay ram

Reputation: 61

Install react-native-fetch-blob to get the path of the file. Below is an example.

pickFile = async () => {
try {
  const res = await DocumentPicker.pick({
    type: [DocumentPicker.types.allFiles],
  });

  console.log(res.uri);
  //output: content://com.android.providers.media.documents/document/image%3A4055

  RNFetchBlob.fs
    .stat(res.uri)
    .then((stats) => {
      console.log(stats.path);
 //output: /storage/emulated/0/WhatsApp/Media/WhatsApp Images/IMG-20200831-WA0019.jpg
    })
    .catch((err) => {
      console.log(err);
    });
} catch (err) {
  if (DocumentPicker.isCancel(err)) {
  } else {
    throw err;
  }
}};

Upvotes: 5

Balaji Rajendran
Balaji Rajendran

Reputation: 367

Try this, maybe it will help you https://www.npmjs.com/package/react-native-file-share-for-android But its support only for Android

const uploadDocunment = async finalSubmit => {
      const granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
        {
          title: 'Storage Permission',
          message: 'App needs access to memory to download the file ',
        },
      );
      if (granted != PermissionsAndroid.RESULTS.GRANTED) {
        ToastAndroid.showWithGravity(
          'You need to give storage permission to download the file',
          ToastAndroid.SHORT,
          ToastAndroid.BOTTOM,
        );
        return false;
      }
      try {
        DocumentPicker.pick({
          type: [DocumentPicker.types.plainText],
        }).then(res => {
          RNFetchBlob.fs.readFile(res.uri, 'utf8').then(text1 => {
            ToastAndroid.showWithGravity(
              'Docunment is Ready!',
              ToastAndroid.SHORT,
              ToastAndroid.BOTTOM,
            );
          });
        });
      } catch (err) {
        if (DocumentPicker.isCancel(err)) {
          ToastAndroid.showWithGravity(
            'File not Selected',
            ToastAndroid.SHORT,
            ToastAndroid.BOTTOM,
          );
        } else {
          throw err;
        }
      }
    };
    uploadDocunment();
  };

Upvotes: 1

Maicon Gilton
Maicon Gilton

Reputation: 691

You may forget to request proper permissions for that like so (andriod only):

export async function requestStoragePermission() {

    if (Platform.OS !== "android") return true

    const pm1 = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE);
    const pm2 = await PermissionsAndroid.check(PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE);

    if (pm1 && pm2) return true

    const userResponse = await PermissionsAndroid.requestMultiple([
        PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
        PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE
    ]);

    if (userResponse['android.permission.READ_EXTERNAL_STORAGE'] === 'granted' &&
        userResponse['android.permission.WRITE_EXTERNAL_STORAGE'] === 'granted') {
        return true
    } else {
        return false
    }
}

Upvotes: 1

Ron Astle Lobo
Ron Astle Lobo

Reputation: 1314

I actually figured this out myself. You can get Absolute path in 3 ways.

The most convenient way : Use react-native-document-picker, on selection it will give you a Relative path, something like this content://com.android....... Pass that Relative path to Stat(filepath) function of the react-native-fetch-blob library. The object will return absolute path. Append the path with file:// to use it for further operations.

The other 2 ways are by using react-native-image picker and CameraRoll (React Native Library)

I hope this helps !

Edit: Please make sure you run the app on hardware device rather than Virtual Device to test it.

Upvotes: 21

Related Questions