0

I've made multipart request to server for sending images from phone gallery according to tutorial, but I don't know what is wrong with it. Server will return 201 response code, but image is not sent correctly to the server.

Here is the HTTPRequest function for sending the image.

fun doPostImage(resources: String, avatarImage: ByteArray, fileName: String): JSONObject{
        val url = SERVER_URL + resources
        val maxBufferSize = 1024 * 1024

        val X_SESSION: String? = context?.getSharedPreferences(context.
                getString(R.string.SharedPrefs), MODE_PRIVATE)?.
                getString(context.getString(R.string.X_SESSION), null)
        createLog("AvatarRequestURL", "POST $url")
        val obj = URL(url)

        val attachmentName = fileName
        val attachmentFileName = fileName + ".jpg"
        val crlf = "\r\n"
        val twoHyphens = "--"
        val boundary = "*****"


        with(obj.openConnection() as HttpURLConnection) {


            requestMethod = "POST"
            doOutput = true
            doInput = true

            val postData: ByteArray = avatarImage

            if (X_SESSION != null){
                createLog("DOPOST-SESSION", X_SESSION)
                setRequestProperty("X-Session", X_SESSION)
            } else {
                createLog("DOPOST-SESSION", "SESSION NULL :(")
            }

            setRequestProperty("Connection", "Keep-Alive")
            setRequestProperty("Cache-Control", "no-cache")
            setRequestProperty("X-API-Key", API_KEY)
            setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary)
            setChunkedStreamingMode(maxBufferSize)

            //constructing request body
            try {
                val writer = PrintWriter(OutputStreamWriter(outputStream, "UTF-8"), true)
                writer.append(twoHyphens + boundary + crlf)
                writer.append("Content-Disposition: form-data; name=\"" + attachmentName + "\";filename=\"" + attachmentFileName + "\"" + crlf)
                writer.append("Content-Type", "image/jpeg")
                writer.append(crlf)
                writer.flush()

                val byteArrayInputStream = ByteArrayInputStream(postData)
                byteArrayInputStream.copyTo(outputStream, maxBufferSize)

            } catch (exception: Exception) {
                createLog("AvatarImageException", exception.toString())
            }

            createLog("Avatar_Upload_Response", "Response Code Image: $responseCode")

            //server response handling
            if (responseCode != HttpURLConnection.HTTP_OK) {
                try {
                    BufferedReader(InputStreamReader(errorStream)).use {
                        val response = StringBuffer()

                        var inputLine = it.readLine()
                        while (inputLine != null) {
                            response.append(inputLine)
                            inputLine = it.readLine()
                        }
                        createLog("AvatarRequest", "Response body Image: $response")
                        return JSONObject(response.toString())
                    }

                } catch (exception: Exception) {
                    return if(responseCode == HttpURLConnection.HTTP_CLIENT_TIMEOUT){
                        createLog("POST EXCEPTION", exception.toString())
                        val errorResponse = JSONObject()
                        errorResponse.put("ErrorCode", responseCode)
                        errorResponse.put("Message", exception.message)
                        errorResponse
                    } else {
                        createLog("EXCEPTION", exception.toString())
                        val errorResponse = JSONObject()
                        errorResponse.put("ErrorCode", responseCode)
                        errorResponse.put("Message", exception.message)
                        return errorResponse
                    }

                }
            } else {
                try {
                    BufferedReader(InputStreamReader(inputStream)).use {
                        val response = StringBuffer()

                        var inputLine = it.readLine()
                        while (inputLine != null) {
                            response.append(inputLine)
                            inputLine = it.readLine()
                        }

                        createLog("AvatarRequest", "Response body Image: $response")
                        return JSONObject(response.toString())
                    }

                } catch (exception: Exception) {
                    throw Exception("Exception while push the notification  $exception")
                }
            }
        }
    }

Here how I get image from gallery:

profilePhotoSelectButton.setOnClickListener {
            val galleryIntent = Intent()
            galleryIntent.type = "image/*"
            galleryIntent.action = Intent.ACTION_GET_CONTENT
            startActivityForResult(Intent.createChooser(galleryIntent, "Choose profile photo"), PICK_PHOTO)

        }

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == PICK_PHOTO){

            val avatarPhoto: Uri? = data?.data
            if (avatarPhoto != null){
                val imageStream: InputStream = contentResolver.openInputStream(avatarPhoto)
                val imageBitmap: Bitmap = BitmapFactory.decodeStream(imageStream)
                val roundedBitMapDrawable: RoundedBitmapDrawable = RoundedBitmapDrawableFactory.create(resources, imageBitmap)
                roundedBitMapDrawable.isCircular = true
                profilePhotoPreview.setImageDrawable(roundedBitMapDrawable)

                val userPhotoToJSON: Bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, avatarPhoto)
                val resizedBitmap: Bitmap = getResizedBitmap(userPhotoToJSON, 150)
                userProfilePhotoEncoded = compressBitmap(resizedBitmap, Bitmap.CompressFormat.JPEG)
                userProfilePhotoPath = avatarPhoto.path
                createLog("AvatarPath ", userProfilePhotoPath.toString())
                userProfilePhotoName = File(avatarPhoto.path).name
                createLog("AvatarName ", userProfilePhotoName.toString())
            }
        }
    }

    private fun compressBitmap(bitmapPicture: Bitmap, compressFormat: Bitmap.CompressFormat): ByteArray {
        val COMPRESSION_QUALITY = 50
        val byteArrayBitmapStream = ByteArrayOutputStream()
        bitmapPicture.compress(compressFormat, COMPRESSION_QUALITY, byteArrayBitmapStream)
        val avatarByteArray: ByteArray = byteArrayBitmapStream.toByteArray()
        return avatarByteArray
    }

    /**
     * reduces the size of the image
     * @param image
     * @param maxSize
     * @return
     */
    fun getResizedBitmap(image: Bitmap, maxSize: Int): Bitmap {
        var width = image.width
        var height = image.height

        val bitmapRatio = width.toFloat() / height.toFloat()
        if (bitmapRatio > 1) {
            width = maxSize
            height = (width / bitmapRatio).toInt()
        } else {
            height = maxSize
            width = (height * bitmapRatio).toInt()
        }
        return Bitmap.createScaledBitmap(image, width, height, true)
    }


api.updateAvatar(userProfilePhotoEncoded!!,userProfilePhotoPath!!, userProfilePhotoName!!, object: IProfileCallback{
                            override fun onError(errorJSON: JSONObject) {
                                createLog("AVATAR_ERROR ", errorJSON.toString())
                            }

                            override fun onSuccess(profileJSON: JSONObject?) {
                                createLog("AVATAR SUCCESS", profileJSON.toString())
                                setResult(MYDATA_UPDATE_RESULT)
                                finish()
                            }

                        })

fun updateAvatar(avatar: ByteArray, filepath: String, fileName: String, callback: IProfileCallback){

        class UpdateProfileAsync(private val profileCallback: IProfileCallback): AsyncTask<Void, Void, JSONObject>() {

            override fun doInBackground(vararg p0: Void?): JSONObject {

                val server = Server.getInstance(context!!)

                return server.doPostImage(context.getString(R.string.profile_avatar_link), avatar, fileName)
            }

            override fun onPostExecute(result: JSONObject?) {
                super.onPostExecute(result)

                if(result!!.has("ErrorCode")){
                    profileCallback.onError(result)
                } else {
                    createLog("SuccessfullyUpdatedProfile", "onSuccess()")
                    profileCallback.onSuccess(result)
                }
            }
        }

        UpdateProfileAsync(callback).execute()
    }
martin1337
  • 2,384
  • 6
  • 38
  • 85

0 Answers0