Okhttp3,retrofit2 POST上的FileNotFoundException

时间:2019-01-19 18:54:12

标签: android kotlin retrofit2 okhttp3

由于我正在显示以下代码的一部分,因此我尝试使用retrofit2发布图像。 Android Studio

我真的不明白是什么错误,希望有人帮助我解决这个问题。

即时贴

q:c

插入请求并进行初始化

import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.Part


interface ImageUploadService {

    @Multipart
    @POST("uploadfile")
    fun saveImage(
        @Part("description") description: RequestBody,
        @Part image: MultipartBody.Part
    ): Call<ResponseBody>
}

活动代码

import com.code.delegate.RequestDelegateOnSuccessFull
import com.code.retrofit.RetrofitInitialize
import com.code.retrofit.service.ImageUploadService
import com.softwareplace.workout.delegate.Delegate
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response


class ImageRequest(url: String) {

    private val service: ImageUploadService = RetrofitInitialize(url)
        .retrofit
        .create(ImageUploadService::class.java)

    fun postImageFile(delegate: Delegate<ResponseBody>, image: MultipartBody.Part, description: RequestBody) {
        service.saveImage(image = image, description = description).enqueue(object : Callback<ResponseBody> {
            override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                delegate.onFailure(t)
            }

            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                RequestDelegateOnSuccessFull(response = response, delegate = delegate).run()
            }

        })
    }
}

当我尝试发布此图像文件时,出现此错误

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.code.R
import com.code.retrofit.request.ImageRequest
import com.softwareplace.workout.delegate.Delegate
import com.softwareplace.workout.glide.GlideImageSet
import com.softwareplace.workout.ui.permission.PICK_FROM_GALLERY
import com.softwareplace.workout.ui.permission.Permission
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.ResponseBody
import org.apache.commons.io.FileUtils
import java.io.File

class MainActivity : AppCompatActivity() {

    private lateinit var selectedImage: Uri

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        userSelectImageProfile()
        postImage()
    }

    private fun postImage() {
        user_register_button.setOnClickListener {

            if (selectedImage != null) {
                var descriptionBody = RequestBody.create(MultipartBody.FORM, "User Image")
                var image = FileUtils.getFile(File(selectedImage.path))

                var filePart = RequestBody.create(
                    MediaType.parse(contentResolver.getType(selectedImage)),
                    image
                )

                var imageFile = MultipartBody.Part.createFormData("file", image.name, filePart)

                ImageRequest(getString(R.string.base_url_file_upload)).postImageFile(
                    image = imageFile,
                    description = descriptionBody, delegate = object : Delegate<ResponseBody> {
                        override fun onSuccessFull(isSuccessFull: Boolean, response: ResponseBody?, message: String?) {
                            if (isSuccessFull) {
                                Log.i("ResponseBody", response.toString())
                            } else {
                                Log.i("ResponseError", message)
                            }
                        }

                        override fun onFailure(exception: Throwable) {
                            Log.i("Error", exception.message)
                            exception.printStackTrace()
                        }

                    })

            }
        }
    }

    private fun userSelectImageProfile() {
        user_image_select.setOnClickListener {
            Permission(this).getReadExternalStoragePemission()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.d("req", "req$requestCode")
        Log.d("res", "res$resultCode")

        if (requestCode == PICK_FROM_GALLERY && resultCode == RESULT_OK && null != data) {
            selectedImage = data.data
            val bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, selectedImage)
            GlideImageSet(context = this).glideImageSet(imageView = user_image_profile, data = bitmap)
        }
    }
}

您会在错误消息中看到,没有这样的文件或目录,似乎无法从路径中找到文件。

1 个答案:

答案 0 :(得分:0)

我做了很多测试,所以我得到了一个解决方案,如下面的代码所示,但是如果您知道更好的解决方案,请告诉我。

private fun postImage() {
    user_register_button.setOnClickListener {

        if (selectedImage != null) {
            var imageFile = File(baseContext.cacheDir, "${System.currentTimeMillis()}")
            imageFile.createNewFile()

            var arrayOutputStream = ByteArrayOutputStream()
            getBitmapFromUri(selectedImage).compress(Bitmap.CompressFormat.JPEG, 100, arrayOutputStream)
            var outputStream = FileOutputStream(imageFile)
            outputStream.write(arrayOutputStream.toByteArray())
            outputStream.flush()
            outputStream.close()


            var descriptionBody = RequestBody.create(MediaType.parse("image/*"), imageFile)
            val imagePart = MultipartBody.Part.createFormData("file", "${System.currentTimeMillis()}", descriptionBody)

            ImageRequest(getString(R.string.base_url_file_upload)).postImageFile(
                image = imagePart, delegate = object : Delegate<ResponseBody> {
                    override fun onSuccessFull(isSuccessFull: Boolean, response: ResponseBody?, message: String?) {
                        if (isSuccessFull) {
                            Log.i("ResponseBody", response.toString())
                        } else {
                            Log.i("ResponseError", message)
                        }
                    }

                    override fun onFailure(exception: Throwable) {
                        Log.i("Error", exception.message)
                        exception.printStackTrace()
                    }

                })

        }
    }
}

@Throws(IOException::class)
private fun getBitmapFromUri(uri: Uri): Bitmap {
    val parcelFileDescriptor = contentResolver.openFileDescriptor(uri, "r")
    val fileDescriptor = parcelFileDescriptor.fileDescriptor
    val image = BitmapFactory.decodeFileDescriptor(fileDescriptor)
    parcelFileDescriptor.close()
    return image
}