0

I have to allow the user to select an image and upload it to the server. I use an Intent with ACTION_GET_CONTENT and get the selected image as a content Uri, so far so good.

To send this file using Retrofit 2, I need a File object. For this, I need a file Uri instead of a content Uri.

    suspend fun uploadPicture(uri: Uri, context: Context){
        // uri is content://com.android.providers.media.documents/document/image%3A115
        val file = File("HERE I NEED A FILE PATH WHICH I CAN'T GET FROM THE URI")

        val part = MultipartBody.Part.createFormData(
            "file",
            file.name,
            RequestBody.create(
                MediaType.parse(context.contentResolver.getType(fileUri) ?: throw Exception("couldn't resolve content type")),
                file
            )
        )
        api.uploadUserPicture(user.apiAccessToken, part)
    }

Google advises to always use the ContentResolver instead of direct file access and file paths, and the solutions to convert the content Uri to a file Uri offered in Android: Getting a file URI from a content URI? no longer work because MediaStore.Images.Media.DATA is deprecated and the column is no longer provided by the ContentResolver query.

So my question: is there a way to send a file described by a content Uri using Retrofit?

  • `To send this file using Retrofit 2, I need a File object. ` No. You can use the uri directly. Google for inputstreamrequestbidy or something like that. You are number ### who comes with this question. It has been solved here quite often. – blackapps Oct 31 '21 at 07:20
  • "To send this file using Retrofit 2, I need a File object" -- no, you need a `RequestBody` implementation that happens to support a `Uri`, rather than a `File`. The accepted answer on the duplicate question links to three such `RequestBody` implementations. – CommonsWare Oct 31 '21 at 10:48

0 Answers0