Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to upload image Uri using retrofit? #205

Closed
Dhaval2404 opened this issue May 20, 2021 · 1 comment
Closed

How to upload image Uri using retrofit? #205

Dhaval2404 opened this issue May 20, 2021 · 1 comment

Comments

@Dhaval2404
Copy link
Owner

Dhaval2404 commented May 20, 2021

You needed to create RequestBody in order to upload the image Uri.

val params = HashMap<String, RequestBody>()
val fileName = InputStreamRequestBody.getFileName(context, uri)
// "file" is your image upload field name
params["file\"; filename=\"${fileName}\""] =  InputStreamRequestBody(context, uri) 
apiService.uploadUri(params) 
interface APIService {

	@Multipart
	@POST("upload")
	suspend fun uploadUri(@PartMap params: Map<String, @JvmSuppressWildcards RequestBody>): Response<JsonObject>

}
import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.provider.OpenableColumns
import android.webkit.MimeTypeMap
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody
import okio.BufferedSink
import okio.source
import java.io.File
import java.io.IOException
import java.util.Locale

class InputStreamRequestBody(
    private val context: Context,
    private val uri: Uri
) : RequestBody() {

    override fun contentType(): MediaType? {
        return getMimeType(context, uri)?.toMediaTypeOrNull()
    }

    @Throws(IOException::class)
    override fun contentLength(): Long {
        return -1
    }

    @Throws(IOException::class)
    override fun writeTo(sink: BufferedSink) {
        sink.writeAll(context.contentResolver.openInputStream(uri)!!.source())
    }

    companion object {

        fun getMimeType(context: Context, uri: Uri): String? {
            return when (uri.scheme) {
                ContentResolver.SCHEME_CONTENT -> context.contentResolver.getType(uri)
                ContentResolver.SCHEME_FILE -> MimeTypeMap.getSingleton().getMimeTypeFromExtension(
                    MimeTypeMap.getFileExtensionFromUrl(uri.toString()).toLowerCase(Locale.US)
                )
                else -> null
            }
        }

        fun getFileName(context: Context, uri: Uri): String? {
            when (uri.scheme) {
                ContentResolver.SCHEME_FILE -> {
                    val filePath = uri.path
                    if (!filePath.isNullOrEmpty()) {
                        return File(filePath).name
                    }
                }

                ContentResolver.SCHEME_CONTENT -> {
                    return getCursorContent(uri, context.contentResolver)
                }
            }

            return null
        }

        private fun getCursorContent(uri: Uri, contentResolver: ContentResolver): String? =
            kotlin.runCatching {
                contentResolver.query(uri, null, null, null, null)?.use { cursor ->
                    val nameColumnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
                    if (cursor.moveToFirst()) {
                        cursor.getString(nameColumnIndex)
                    } else null
                }
            }.getOrNull()

    }

}

Please add a comment below if you need more help on this.

@Faisal-Naseer
Copy link

I am getting this while when i use the image from docment gallery
Permission Denial: opening provider com.android.providers.downloads.DownloadStorageProvider from ProcessRecord

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants