Android Kotlin AsyncHttpHandler make Http POST, GET, FILES Request to Server

masterjosh
by
masterjosh
Jan 09, 2019
Android Kotlin AsyncHttpHandler make Http POST, GET, FILES Request to Server

Hi Dev,

my AsyncHttpHandler() Codes i used in my ongoing project netmeme App...

What does this do ?

AsyncHttpHandler() make asynchronous request to your server, 

  • you can use this piece of codes to upload File from android app to your server, 
  • make POST request to your server
  • make GET request to your server

Can i upload file and send $_POST data ?

yes

Now Let's get started!

Step 1

Create Kotlin Class name it AsyncHttpHandler

Step 2

Make the Class open class by this 


open class AsyncHttpHandler {
}

Step 3

Add Interface Listener to your AsyncHttpHandler Class


interface Listener {
    fun onStart(){}
    fun onProgress(result: Int){}
    fun onSuccess(result: String?){}
    fun onFailed(result: String?){}
}

Step 4

Set the listener and Add setListener method to the class


private var mListener: Listener = object : Listener {
}
fun setListener(listener: Listener): AsyncHttpHandler{
    mListener = listener
    return this
}

Step 5

Add inner AysncTask class name MakeServiceCallGet 



    @SuppressLint("StaticFieldLeak")
    inner class MakeServiceCallGet : AsyncTask<String,Void,String?>(){
        override fun onPreExecute() {
            mListener.onStart()
        }
        override fun doInBackground(vararg urls: String?): String? {
            var response: String? = null
            try {
                val url = URL(urls[0])
                val conn = url.openConnection() as HttpURLConnection
                conn.requestMethod = "GET"
                // read the response
                val input = BufferedInputStream(conn.inputStream)
                response = if (conn.responseCode == HttpURLConnection.HTTP_OK) {
                    // read the response
                    convertStreamToString(input)
                } else {
                    null
                }
            } catch (e: MalformedURLException) {
                Log.e(TAG, "MalformedURLException: " + e.message)
            } catch (e: ProtocolException) {
                Log.e(TAG, "ProtocolException: " + e.message)
            } catch (e: IOException) {
                Log.e(TAG, "IOException: " + e.message)
            } catch (e: Exception) {
                Log.e(TAG, "Exception: " + e.message)
            }
            return response
        }
        override fun onPostExecute(result: String?) {
            if (result == null){
                mListener.onFailed(result)
            } else {
                mListener.onSuccess(result)
            }
        }
    }

Step 6

Add another AsyncTask class name MakeServiceCallPostWithFile



    @SuppressLint("StaticFieldLeak")
    inner class MakeServiceCallPostWithFile(val params: JSONObject) : AsyncTask<String,Int,String?>(){
        override fun onPreExecute() {
            mListener.onStart()
        }
        override fun doInBackground(vararg urls: String?): String? {
            var response: String? = null
            try {
                val boundary = "*****"
                val lineEnd = "\r\n"
                val twoHyphens = "--"
                val url = URL(urls[0])
                val conn = url.openConnection() as HttpURLConnection
                conn.readTimeout = 15000
                conn.connectTimeout = 15000
                conn.requestMethod = "POST"
                conn.doInput = true
                conn.doOutput = true
                conn.useCaches = false
                conn.setRequestProperty("Connection", "Keep-Alive")
                conn.setRequestProperty("ENCTYPE", "multipart/form-data")
                conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=$boundary")
                val dos = DataOutputStream(conn.outputStream)
                val itr = params.keys()
                while (itr.hasNext()) {
                    val key = itr.next()
                    val value = params.get(key)
                    when(value){
                        is File -> {
                            var bytesRead: Int
                            var bytesAvailable: Int
                            var bufferSize: Int
                            val maxBufferSize = 1 * 1024 * 1024
                            val fileInputStream = FileInputStream(value)
                            dos.writeBytes(twoHyphens + boundary + lineEnd)
                            dos.writeBytes("Content-Disposition: form-data; name=\"$key\";filename=\"${value.path}\"$lineEnd")
                            dos.writeBytes("Content-Type: ${Constants.fileMimeType(value.path)}$lineEnd")
                            dos.writeBytes(lineEnd)
                            // create a buffer of maximum size
                            bytesAvailable = fileInputStream.available()
                            bufferSize = Math.min(bytesAvailable, maxBufferSize)
                            val buffer = ByteArray(bufferSize)
                            // read file and write it into form...
                            bytesRead = fileInputStream.read(buffer, 0, bufferSize)
                            var process: Int
                            while (bytesRead > 0) {
                                dos.write(buffer, 0, bufferSize)
                                //Progress
                                process = (bufferSize * 100 / bytesAvailable)
                                publishProgress(process)
                                bytesAvailable = fileInputStream.available()
                                bufferSize = Math.min(bytesAvailable, maxBufferSize)
                                bytesRead = fileInputStream.read(buffer, 0, bufferSize)
                            }
                            // send multipart form data necesssary after file
                            // data...
                            dos.writeBytes(lineEnd)
                            fileInputStream.close()
                        }
                        else -> {
                            dos.writeBytes(twoHyphens + boundary + lineEnd)
                            dos.writeBytes("Content-Disposition: form-data; name=\"$key\"$lineEnd")
                            dos.writeBytes("Content-Type: text/plain$lineEnd")
                            dos.writeBytes(lineEnd)
                            dos.writeBytes(URLEncoder.encode("$value", "UTF-8"))
                            dos.writeBytes(lineEnd)
                        }
                    }
                }
                dos.writeBytes(twoHyphens + boundary + twoHyphens
                        + lineEnd)
                // Responses from the server (code and message)
                val responseCode = conn.responseCode
                val serverResponseMessage = conn
                        .responseMessage
                response = if (responseCode == HttpsURLConnection.HTTP_OK) {
                    // read the response
                    val `in` = BufferedInputStream(conn.inputStream)
                    convertStreamToString(`in`)
                } else {
                    serverResponseMessage
                }
                // close the streams //
                dos.flush()
                dos.close()
            } catch (e: MalformedURLException) {
                Log.e(TAG, "MalformedURLException: " + e.message)
            } catch (e: ProtocolException) {
                Log.e(TAG, "ProtocolException: " + e.message)
            } catch (e: IOException) {
                Log.e(TAG, "IOException: " + e.message)
            } catch (e: Exception) {
                Log.e(TAG, "Exception: " + e.message)
            }
            return response
        }
        override fun onProgressUpdate(vararg values: Int?) {
            super.onProgressUpdate(*values)
            mListener.onProgress(values[0] ?: 0)
        }
        override fun onPostExecute(result: String?) {
            if (result == null){
                mListener.onFailed(result)
            } else {
                mListener.onSuccess(result)
            }
        }
    }

Step 7

Add convertStreamToString method, this convert inputstream to strings, i used this to convert stream response from server to string


private fun convertStreamToString(`is`: InputStream): String {
//        val reader = BufferedReader(InputStreamReader(`is`))
        val sb = StringBuilder()
        try {
            BufferedReader(InputStreamReader(`is`)).use { r ->
                r.lineSequence().forEach {
                    sb.append(it).append('\n')
                }
            }
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            try {
                `is`.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        return sb.toString()
    }

Step 8

Add companion object



    companion object {
        private val TAG = AsyncHttpHandler::class.java.simpleName
    }

Usage


val asyncHttpHandler = AsyncHttpHandler()
            asyncHttpHandler.setListener(object : AsyncHttpHandler.Listener {
                override fun onStart() {
                    super.onStart()
                    
                }
                @SuppressLint("SetTextI18n")
                override fun onProgress(result: Int) {
                    Log.d("upload_progress", "$result")
                }
                @SuppressLint("SetTextI18n")
                override fun onSuccess(result: String?) {
                    Log.d("upload_data", "$result")
                }
                override fun onFailed(result: String?) {
                    Log.d("upload_data_fail", "$result")
                }
            })
            val params = JSONObject()
            params.put("username","masterjosh")
            params.put("caption","Happy Dev")
            params.put("uploaded_file",File("/sdcard/masterjosh.png"))
            asyncHttpHandler.MakeServiceCallPostWithFile(params).execute("https://masterjosh.site/upload.php")
        

Full Code has been attached...

Download AsyncHttpHandler.kt (11.09 KB) (Hits 218)



Add Comment