Skip to content

Instantly share code, notes, and snippets.

@cketti
Created March 27, 2019 14:59
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cketti/8ac927509787d7085a5ef8f866806f0f to your computer and use it in GitHub Desktop.
Save cketti/8ac927509787d7085a5ef8f866806f0f to your computer and use it in GitHub Desktop.
Implementation of OkHttp's RequestBody that supports Android's content:// URIs
import android.content.ContentResolver
import android.net.Uri
import okhttp3.MediaType
import okhttp3.RequestBody
import okio.BufferedSink
import okio.Okio
import java.lang.IllegalStateException
class ContentUriRequestBody(
private val contentResolver: ContentResolver,
private val contentUri: Uri
) : RequestBody() {
override fun contentType(): MediaType? {
val contentType = contentResolver.getType(contentUri) ?: return null
return MediaType.parse(contentType)
}
override fun writeTo(sink: BufferedSink) {
val inputStream = contentResolver.openInputStream(contentUri)
?: throw IllegalStateException("Couldn't open content URI for reading: $contentUri")
Okio.source(inputStream).use { source ->
sink.writeAll(source)
}
}
}
@cketti
Copy link
Author

cketti commented May 26, 2020

I believe the issue is that S3 doesn't support the 'chunked' transfer encoding for uploads. This is what OkHttp will use for large files when the RequestBody doesn't specify a size. You can help OkHttp out by implementing the contentLength() method. To get the size of a document you could use DocumentFile.length().

@prabhat-oodles
Copy link

@cketti What if we want to know the file size to get the progress of upload?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment