【问题标题】:Okhttp3, FileNotFoundException on retrofit2 POSTOkhttp3,retrofit2 POST 上的 FileNotFoundException
【发布时间】:2019-01-19 18:54:11
【问题描述】:

当我在下面显示部分代码时,我正在尝试使用 retrofit2 发布图像。 Android 工作室

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

图片服务

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)
        }
    }
}

当我尝试发布这个图像文件时,我得到了这个错误

I/Error: /raw/storage/emulated/0/DCIM/Camera/IMG_20190109_141817_HDR.jpg (No such file or directory)
W/System.err: java.io.FileNotFoundException: /raw/storage/emulated/0/DCIM/Camera/IMG_20190109_141817_HDR.jpg (No such file or directory)
W/System.err:     at java.io.FileInputStream.open0(Native Method)
W/System.err:     at java.io.FileInputStream.open(FileInputStream.java:200)
        at java.io.FileInputStream.<init>(FileInputStream.java:150)
        at okio.Okio.source(Okio.java:168)
W/System.err:     at okhttp3.RequestBody$3.writeTo(RequestBody.java:119)
        at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173)
W/System.err:     at okhttp3.MultipartBody.writeTo(MultipartBody.java:114)
        at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:72)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
W/System.err:     at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
W/System.err:     at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
W/System.err:     at okhttp3.RealCall$AsyncCall.execute(RealCall.java:200)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)

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

【问题讨论】:

    标签: android kotlin retrofit2 okhttp3


    【解决方案1】:

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

    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
    }
    

    【讨论】:

      猜你喜欢
      • 2017-09-05
      • 2017-06-05
      • 2017-08-24
      • 2018-05-22
      • 1970-01-01
      • 2017-10-28
      • 2018-01-09
      • 1970-01-01
      • 2019-05-11
      相关资源
      最近更新 更多