【问题标题】:Kotlin retrofit upload image not found未找到 Kotlin 改造上传图片
【发布时间】:2021-07-05 15:04:53
【问题描述】:

我正在尝试从图库中发送照片,但出现错误提示找不到图片

请求甚至没有到达服务器

在片段中

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == Activity.RESULT_OK) {
        when (requestCode) {
            REQUEST_SELECT_IMAGE_IN_ALBUM -> {
                val contentURI = data!!.data
                postServer(contentURI)

            }
        }
    }
}

private fun postServer(contentURI: Uri) {

    val MEDIA_TYPE_IMAGE: MediaType = MediaType.parse("image/*")!!
    val file = File(contentURI.path)
    val requestBody: RequestBody = RequestBody.create(MEDIA_TYPE_IMAGE, file)
    mercrediViewModel.uploadImage(enfant, requestBody)
}

在我的模型中

fun uploadImage(enfant: Enfant, requestBody: RequestBody) {
    viewModelScope.launch {

        val request = mercrediService.uploadImage("****", enfant.id, requestBody)
        request.enqueue(object : Callback<ResponseBody> {
            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                Timber.i(" error image" + t)
            }

            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                Timber.i(" response image" + response.body())
            }

        })
    }
}

及改装服务

@Multipart
@POST("api/update/enfant/photo/{id}")
fun uploadImage(
    @Header("X-AUTH-TOKEN") token: String?,
    @Path("id") id: Int,
    @Part("image") image: RequestBody
): Call<ResponseBody>

我有这个错误

好的,谢谢,我已经改了这个错误信息是一样的:

I/MercrediViewModel$uploadImage:zeze 错误图像 java.io.FileNotFoundException: /document/image:74 (没有这样的文件或目录) 在 java.io.FileInputStream.open(本机方法) 在 java.io.FileInputStream.(FileInputStream.java:146) 在 okio.Okio.source(Okio.java:168) 在 okhttp3.RequestBody$3.writeTo(RequestBody.java:119) 在 okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173) 在 okhttp3.MultipartBody.writeTo(MultipartBody.java:114) .....

谢谢

【问题讨论】:

  • 您最大的错误是有缺陷的异常日志记录。永远不要使用 Exception#message 进行调试,要么打印整个堆栈跟踪 (Timber.i(t, "error image")),要么至少打印整个堆栈跟踪 (" error image" + t),因为您确定不需要堆栈跟踪,因为并非每个异常都有消息,甚至如果它有一个,它几乎是无用的。更改它,然后将完整的堆栈跟踪添加到您的问题中,以便有机会找出问题所在。
  • 好的,谢谢我已经更新了我的错误信息
  • ... 部分实际上很有趣,不要打断它。无论如何,您遇到的问题是您尝试上传的文件不是常规文件,而是来自内容提供者的项目。 /document/image:74 在 android 文件系统中不存在。请参阅commonsware.com/blog/2016/03/15/how-consume-content-uri.html 您需要ContentResolver#openInputStream()(例如developer.android.com/guide/topics/providers/…)并构建一个RequestBody,而不是使用File,而是使用byte[]。或查看github.com/square/okhttp/issues/3585 了解更多想法

标签: android kotlin retrofit2


【解决方案1】:

最后我的解决方案

class FileHelper {

fun createFile(realPath: String): File {
    return File(realPath)
}

fun createRequestBody(file: File): RequestBody {
    val MEDIA_TYPE_IMAGE: MediaType = MediaType.parse("image/*")!!
    return RequestBody.create(MEDIA_TYPE_IMAGE, file)
}

fun createPart(file: File, requestBody: RequestBody): MultipartBody.Part {
    return MultipartBody.Part.createFormData("image", file.name, requestBody)
}

fun getPathFromURI(context: Context, uri: Uri): String? {
    val path: String = uri.path
    var realPath: String? = null

    val databaseUri: Uri
    val selection: String?
    val selectionArgs: Array<String>?
    if (path.contains("/document/image:")) { // files selected from "Documents"
        databaseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
        selection = "_id=?"
        selectionArgs = arrayOf(DocumentsContract.getDocumentId(uri).split(":")[1])
    } else { // files selected from all other sources, especially on Samsung devices
        databaseUri = uri
        selection = null
        selectionArgs = null
    }
    try {
        val projection = arrayOf(
            MediaStore.Images.Media.DATA,
            MediaStore.Images.Media._ID,
            MediaStore.Images.Media.ORIENTATION,
            MediaStore.Images.Media.DATE_TAKEN
        ) // some example data you can query
        val cursor = context.contentResolver.query(
            databaseUri,
            projection, selection, selectionArgs, null
        )
        if (cursor.moveToFirst()) {
            val columnIndex = cursor.getColumnIndex(projection[0])
            realPath = cursor.getString(columnIndex)
        }
        cursor.close()
    } catch (e: Exception) {
        Timber.i("zeze get path error " + e.message)
    }
    return realPath
}

}

@Multipart
@POST("api/update/enfant/photo/{id}")
fun uploadImage(
    @Path("id") enfantId: Int,
    @Part file: MultipartBody.Part,
    @Part("image") requestBody: RequestBody): Call<ResponseBody>

【讨论】:

    猜你喜欢
    • 2020-05-13
    • 2021-05-08
    • 2018-04-27
    • 2019-07-19
    • 2018-12-08
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    • 2015-09-16
    相关资源
    最近更新 更多