16

I am trying to upload images from cameraRoll. Thing is the cameraRoll component returns content:// URI rather than an actual file path. For uploading the image I need a file path, is there any way to convert content:// URI to file URI? Thanks

cubbuk
  • 7,800
  • 4
  • 35
  • 62
  • why do you need a path? cannot you use an `InputStream` for example? – pskink Mar 28 '16 at 09:25
  • I am developing a React-Native application and using Java methods is a bit cumbersome, so I am looking for a react native solution. Thanks – cubbuk Mar 28 '16 at 09:39

3 Answers3

12

I took the function submitted by @Madhukar Hebbar and made it into a React Native Node Module.

You can find it here: react-native-get-real-path

Thus to achieve what you want, you can use the above module in conjunction with react-native-fs

You can then do something like this when you want to upload the selected image from Camera Roll:

RNGRP.getRealPathFromURI(this.state.selectedImageUri).then(path =>
  RNFS.readFile(path, 'base64').then(imageBase64 =>
    this.props.actions.sendImageAsBase64(imageBase64)
  )
)
Antoni4
  • 2,535
  • 24
  • 37
  • You are a saviour man! Just one concern - as it works only for android - need to put the require package line inside the platform checking logic. However comparing with the utility it is providing - I can ignore this. :-) – Himel Nag Rana Nov 06 '17 at 13:58
  • I have used your library but it didn't work. I get an error that `undefined is not a function(reactNativeGetRealPath2.default.getRealPathFromUri(path))` and the path that I give is `content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F890/ORIGINAL/NONE/225703422` – P.Lorand Feb 07 '18 at 12:46
  • 4
    is there any library which gives support for both ios and android – YLS Jul 17 '18 at 15:38
8

You can use react-native-fs's copyFile method to convert content uri to file uri.

if (url.startsWith('content://')) {
    const urlComponents = url.split('/')
    const fileNameAndExtension = urlComponents[urlComponents.length - 1]
    const destPath = `${RNFS.TemporaryDirectoryPath}/${fileNameAndExtension}`
    await RNFS.copyFile(url, destPath)
}

Then you can use 'file://' + destPath as expected

CoatedMoose
  • 3,624
  • 1
  • 20
  • 36
fujianjin6471
  • 5,168
  • 1
  • 36
  • 32
  • Please note: 1. There are couple of variable name mistakes in the code. 2. If your filename is having '%' symbol in it, then it will not be uploaded. So, replace such characters. – Om Sao Feb 22 '21 at 09:45
2

Pass the content:// URI to below method to get the file path as string and then use the file object to do any operation.

File file = new File(getURIPath(uriValue));

/**
 * URI Value
 * @return File Path.
 */
String getURIPath(Uri uriValue) 
    {
        String[] mediaStoreProjection = { MediaStore.Images.Media.DATA };
        Cursor cursor = getContentResolver().query(uriValue, mediaStoreProjection, null, null, null);
        if (cursor != null){ 
        int colIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        String colIndexString=cursor.getString(colIndex);
        cursor.close();
        return colIndexString;
        }
        return null;
    }
Madhukar Hebbar
  • 3,113
  • 5
  • 41
  • 69