Загрузить изображение с Android на сервер, который принимает только JPEG и PNG - PullRequest
0 голосов
/ 05 марта 2020

MediaStore.Images.Media.Data устарела, поэтому я попытался использовать байтовый массив, но мой сервер выдает ошибку, что он принимает только типы файлов jpeg и png. Я прочитал ответы @ commonsware пару раз из других вопросов, но, похоже, не могу понять это правильно. Как получить тип файла, а также изображение, чтобы его можно было присоединить к моему сетевому вызову? Заранее спасибо

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode == RESULT_OK && requestCode == PROFILE_REQUEST_CODE) {
            val uri = data?.data
            createImageData(uri)
            profile_image.setImageURI(data?.data)
        }
    }
 private fun createImageData(uri: Uri?) {
        val inputStream = activity?.contentResolver?.openInputStream(uri!!)
        processImage(inputStream)
    }

    private fun processImage(inputStream: InputStream?) {
        imageData = inputStream?.readBytes()
        bitmap = BitmapFactory.decodeStream(inputStream)
        val imageBody: RequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), imageData!!)
        val image: MultipartBody.Part = MultipartBody.Part.createFormData("image", "user", imageBody)
        uploadImage(image)
    }

    private fun uploadImage(image: MultipartBody.Part) {
        val user = appPreferences?.getUser()
        val userToken = user?.jwt_token
        val token = "Bearer $userToken"
        val headers = HashMap<String, String>()

        //headers["Authorization"] = token
        val uploadResponseCall: Call<ProfileImageResponse> = client.getApi().upload(token, image)
        uploadResponseCall.enqueue(object : retrofit2.Callback<ProfileImageResponse> {
            override fun onResponse(call: Call<ProfileImageResponse>, response: Response<ProfileImageResponse>) {
                val imageResponse = response.body()
                val resCode = imageResponse?.statuscode
                val msg = imageResponse?.message
                if (resCode == 200) {
                    appUtils.showSnackBar(requireActivity().applicationContext, profile_frame, msg!!)
                } else {
                    appUtils.showSnackBar(requireActivity().applicationContext, profile_frame, "wrong file type")
                }
            }

            override fun onFailure(call: Call<ProfileImageResponse>, t: Throwable) {
                if (t is IOException) {
                    call.cancel()
                    Log.d("profilefragment", "issue")
                    appUtils.showSnackBar(requireActivity().applicationContext, profile_frame, "server error")
                }
            }
        })

    }

Ответы [ 2 ]

0 голосов
/ 05 марта 2020

Вот пример

  @Multipart
    @POST(ApiConstants.SIGNUP)
    fun signUp(
        @Query("first_name") firstName: String,
        @Query("last_name") lastName: String,
        @Query("email") email: String,
        @Query("password") password: String,
        @Query("gender") gender: String,
        @Query("phone_code") phoneCode: String,
        @Query("phone_no") phoneNo: String,
        @Part("id_card_front\"; filename=\"pp.png") id_card_front: RequestBody?
) :  Observable<SignUpModel>

Вот использование

var image = RequestBody.create(
                MediaType.parse("image/*"),
                getFileFromBitmap((imageview.drawable as BitmapDrawable).bitmap, 13)
            )
    disposable = retroClient.signUp(
                fname,
                lname,
                email,
                password,
                gender,
                phoneCode,
                phone,
                image,

            )
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({ result ->
                    Log.d("response", result.toString())

                }, { error ->

                    Log.e("error", error.toString())
                })

метод используется для получения файла из растрового изображения

 fun getFileFromBitmap(bitmap: Bitmap, index: Int): File {
        val f = File(cacheDir, "something+$index")
        f.createNewFile()
        val bitmap = bitmap
        bitmap
        val bos = ByteArrayOutputStream()
        bitmap.compress(Bitmap.CompressFormat.PNG, 25 /*ignored for PNG*/, bos)
        val bitmapdata = bos.toByteArray()
        val fos = FileOutputStream(f)
        fos.write(bitmapdata)
        fos.flush()
        fos.close()

        return f
    }
0 голосов
/ 05 марта 2020

Попробуйте добавить соответствующий заголовок Content-Type. image/png или image/jpg должны соответствовать. Также, возможно, не должно быть многочастного запроса. Так что вам понадобится такой запрос.

private fun processImage(inputStream: InputStream?) {
        imageData = inputStream?.readBytes()
        bitmap = BitmapFactory.decodeStream(inputStream)
        val imageBody: RequestBody = imageData!.toRequestBody() 
        uploadImage(imageBody)
}

или если это действительно должны быть multipart / form-data, вы должны правильно установить тип mime для части изображения следующим образом:

 private fun processImage(inputStream: InputStream?) {
        imageData = inputStream?.readBytes()
        bitmap = BitmapFactory.decodeStream(inputStream)
        val imageBody: RequestBody = RequestBody.create(MediaType.parse("image/png"), imageData!!)
        val image: MultipartBody.Part = MultipartBody.Part.createFormData("image", "user", imageBody)
        uploadImage(image)
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...