0

Given that at some point I have a URI given to me by some external library, and all FileProvider setup is done correctly (and the URI has been granted read/write permissions), how could I get the path to image on disk that the URI is pointing to?

Let's suppose that the image file is stored at /sdcard/XYZAppFolder/file.jpg.

While in debug I can see the string of the URI:

content://<applicationID>.provider/<virtualfolder>/file.jpg

But when trying to perform a query via ContentResolver, I get index -1:

Cursor cursor = contentResolver.query(contentURI, null, null, null, 
cursor.moveToFirst();
int idx = cursor.getColumnIndex(Images.ImageColumns.DATA);


<paths>
<external-path
        name="virtualfolder"
        path="VISUAPP" />
</paths>

Manifest:

<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

Any other way to get the absolute path?

Vito Valov
  • 1,765
  • 1
  • 19
  • 37

1 Answers1

1

how could I get the path to image on disk that the URI is pointing to?

You can't, if by "external library" you mean "a third-party app". Also, it is unlikely that you will have access to the file on the filesystem, anyway:

  • It may be in internal storage
  • It may be in the other app's app-specific location on removable storage
  • It may be in locations on external storage which your app cannot access on Android Q (by default with a targetSdkVersion of 29 or higher) or Android R (for all apps, apparently)

If by "external library" you mean a library in your own app, you could try reading in the FileProvider metadata XML resource and use that to figure out what root and path match the <virtualfolder> path segment. From there, you could generate a File that points to the location from that root, the metadata path, and the rest of the Uri path.

But when trying to perform a query via ContentResolver, I get index -1:

FileProvider does not support a DATA column. Android Q and higher also block the DATA column from similar sorts of queries (e.g., on MediaStore), so any code that you have that relies on it is likely to have problems starting very soon.

Use ContentResolver (e.g., openInputStream()) to work with the Uri.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • is Android R available anywhere ? – Vivek Mishra Jun 18 '19 at 11:56
  • @VivekMishra: That is the 2020 major release. BTW, I may have misinterpreted "external library" -- see the updated answer. – CommonsWare Jun 18 '19 at 11:57
  • @CommonsWare then how do i sent the image to server? I need the image path and without getting imagepath i can't create multipart request to server to upload the image. – sak Aug 01 '20 at 07:35
  • @sak: Quoting [this answer](https://stackoverflow.com/a/56308643/115145): "[This blog post](https://commonsware.com/blog/2020/07/05/multipart-upload-okttp-uri.html) demonstrates how to use `InputStreamRequestBody` (specifically a Kotlin port of the original) to upload content in this fashion. [This blog post](https://cketti.de/2020/05/23/content-uris-and-okhttp/) provides another look at the same problem and a similar solution." – CommonsWare Aug 01 '20 at 11:05