Загрузить изображение с помощью модифицированного Android kotlin

#android #kotlin #retrofit

#Android #kotlin #модернизация

Вопрос:

в моем проекте мне нужно отправить изображение в Rest Api, я использую модификацию 2.0.9 с помощью сопрограммы kotlin. проблема, когда я отправляю запрос, я получаю 201 в качестве кода ответа, который означает, что он успешен, но на сервере я не могу найти изображение, я нахожу только: имя файла, идентификатор файла.

    • возьмите код изображения в моем фрагменте
 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    updatePagesAppBarrTitle()
    if (ActivityCompat.checkSelfPermission(
            requireActivity(),
            android.Manifest.permission.CAMERA
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        ActivityCompat.requestPermissions(
            requireActivity(),
            arrayOf(android.Manifest.permission.CAMERA),
            111
        )
    } else {
        val i = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        startActivityForResult(i, 101)
    }


    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        Log.d("sara1997", "$requestCode")
        if (requestCode == 101) {
            try {
                val picture: Bitmap? = data?.getParcelableExtra("data")
                if (picture != null) {
                    saveImageState(picture)
                    val file = convertBitmapToFile("imageName", picture)
                    val requestBody = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
                    val image =
                        MultipartBody.Part.createFormData("userImage", file.name, requestBody)
                    Picasso.get().load(file.toURL().toString()).into(Takeimageview)
                    _Takepicturebinding.ShowAlertDialogbtn.setOnClickListener {
                        takePictureViewModel.uploadPhoto(
                            image,
                            ImageUploadModel(
                                "page",
                                "ImageCreated",
                                "dfdd0daf-87ae-4cb3-9181-5cb1e240c3e7",
                                "478c60dc-329d-475b-81a3-fbe1a5a118b4",) )
              
                  }       }
 

мой код репозитория

  suspend fun uploadPhoto(
        image: MultipartBody.Part,
        imageUploadModel: ImageUploadModel
    ): Response<ImageUploadModel> {
        val name: RequestBody =
            imageUploadModel.name.toRequestBody("multipart/form-data".toMediaTypeOrNull())
        val corpus: RequestBody = imageUploadModel.corpus.toString()
            .toRequestBody("multipart/form-data".toMediaTypeOrNull())
        val parent: RequestBody = imageUploadModel.parent.toString()
            .toRequestBody("multipart/form-data".toMediaTypeOrNull())
        val type: RequestBody =
            imageUploadModel.type.toRequestBody("multipart/form-data".toMediaTypeOrNull())
        return ApiService.APIBody.uploadPhoto(type, name, corpus, parent, image)
    }
 

мой запрос кода вызова :

 @Multipart
@POST("elements/create/")
suspend fun uploadPhoto(
    @Part("type") type: RequestBody,
    @Part("name") name: RequestBody,
    @Part("corpus") corpus: RequestBody,
    @Part("parent") parent: RequestBody,
    @Part image: MultipartBody.Part
): Response<ImageUploadModel>
 

Ответ №1:

Чтобы опубликовать / разместить MultiPart.Parts, нам нужно сделать это

  1. Убедитесь, что веб-сервис / метод аннотирован правильно
     @Multipart
    @PUT("/api/profile-picture")
    fun putProfilePicture(@Part imagePart: MultipartBody.Part): Single<Response<ResponseBody>>
     
  2. Создайте данные формы
     val imagePart = MultipartBody.Part.createFormData(
           name = "file",
           filename = image.name,
           body = image.asRequestBody("image/*".toMediaTypeOrNull())
    )
     
  3. Отправить запрос
     return webService.putProfilePicture(imagePart)
     

Ответ №2:

сначала сохраните свое изображение

 private fun saveToInternalStorage(bitmapImage: Bitmap, imageName: String): String? {
val cw = ContextWrapper(context)
// path to /data/data/yourapp/app_data/imageDir
val directory: File = cw.getDir("profile_image", Context.MODE_PRIVATE)
// Create imageDir
val mypath = File(directory, imageName)
var fos: FileOutputStream? = null
try {
    fos = FileOutputStream(mypath)
    // Use the compress method on the BitMap object to write image to the OutputStream
    bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos)
} catch (e: java.lang.Exception) {
    e.printStackTrace()
} finally {
    try {
        fos?.close()
    } catch (e: IOException) {
        e.printStackTrace()
    }
}
return directory.getAbsolutePath()}
 

затем используйте OkHttpClient

  saveToInternalStorage(imageView.drawable.toBitmap(), "profile.png")
val cw = ContextWrapper(context)
// path to /data/data/yourapp/app_data/imageDir
val path: File = cw.getDir("profile_image", Context.MODE_PRIVATE)
val file = File(path, "profile.png")

val requestBody =
    MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("id", ID)
        // Upload parameters
        .addFormDataPart(
            "user_image",
            file?.name,
            file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
        ) // Upload files
        .build()
var request = Request.Builder().url("https://www.yoururl.com").post(requestBody).build()

var client = OkHttpClient()
client
    .newCall(request)
    .enqueue(
        object : Callback {
            override fun onFailure(call: Call, e: IOException) {}

            override fun onResponse(call: Call, response: Response) {}
        }
    )
 

https://gist.github.com/samiullahazizi/e2f6e01253ec0a9fe998d4d4b32d67e4