Create a file from a photo URI on Android

To allow the user to select the pictures I have the following in my Fragment:

This code is using ACTION_GET_CONTENT. Particularly on Android 7.0+, generally that will return Uri values with a content scheme. Your code assumes that you are getting Uri values with a file scheme, where the path actually has meaning. Moreover, your code assumes that the user is picking files on the filesystem that you can access, and there is nothing that forces the user to do that. ACTION_GET_CONTENT can be supported by apps where their content is:

  • A local file on external storage
  • A local file on internal storage for the other app
  • A local file on removable storage
  • A local file that is encrypted and needs to be decrypted on the fly
  • A stream of bytes held in a BLOB column in a database
  • A piece of content on the Internet that needs to be downloaded by the other app first
  • Content that is generated on the fly
  • …and so on

Instead of using RequestBody.create(), use the InputStreamRequestBody from this OkHttp issue comment. You provide the same media type as before, but instead of a File (that you are incorrectly creating), you provide a ContentResolver (from getContentResolver() on a Context) and the Uri.

This blog post demonstrates how to use InputStreamRequestBody (specifically a Kotlin port of the original) to upload content in this fashion. This blog post provides another look at the same problem and a similar solution.

Leave a Comment