1

I tried to build some speech recognition app on Android, using kaldi(Audio Speech Recognition software) on local server. I'd like to post WAV file to local server. I found this article:

How to upload a WAV file using URLConnection

and followed & with some other references, I wrote a code but it doesn't work properly.

I got the sentence Array() as $_FILE in php. I think the way to POST binary is wrong, but I can't figure out what's wrong...

My MainActivity.kt (part)

private class UploadFileTask : AsyncTask<Void, Void, Void>(){
    override fun doInBackground(vararg params: Void): Void? {
        var con: HttpURLConnection? = null
        try {
            Log.i("POST","Start POST")
            con = POST_URL.openConnection() as HttpURLConnection
            con.connectTimeout = 300000
            con.setRequestProperty("Accept-Charset", "UTF-8")
            con.setRequestProperty("Connection", "Keep-Alive")
            con.setRequestProperty("Cache-Control", "no-cache")
            con.setRequestProperty("Content-Type", "audio/wav")
            con.requestMethod = "POST"
            con.instanceFollowRedirects = false
            con.doInput = true
            con.doOutput = true
            val wavFile = File(wavPath)
            var postData: ByteArray? = null
            if (wavFile.exists()) {
                Log.i("FILE", "kaldi.wav detected")
                postData = wavFile.readBytes()
            }

            if (postData != null) {
                con.setRequestProperty("charset", "utf-8")
                con.setRequestProperty("Content-length", postData.size.toString())
                Log.i("POST", "exec post")

                con.connect()

                try {
                    val outputStream = DataOutputStream(con.outputStream)
                    outputStream.write(postData)
                    outputStream.flush()
                    outputStream.close()
                } catch (e: Exception) {
                    Log.e("POST", "Exception occurred!")
                }
                val status = con.responseCode
                Log.i("STATUS", Integer.toString(status))

                when (status) {
                    HttpURLConnection.HTTP_OK -> {
                        val inputStream = con.inputStream
                        val reader = BufferedReader(InputStreamReader(inputStream))
                        var httpSource = ""
                        var str = reader.readLine()
                        while (str != null){
                            httpSource += str
                            str = reader.readLine()
                        }
                        Log.i("HTTPSOURCE", "source:$httpSource")
                        inputStream.close()
                    } HttpURLConnection.HTTP_UNAUTHORIZED ->{
                        Log.e("POST", "UNAUTHORIZED")
                    } else -> {
                        Log.i("POST", "CODE IS " + Integer.toString(status))
                    }
                }

            }
            con.disconnect()

        } catch (e: InterruptedException){
            Log.e("UPLOADER", "aborting.")
        } finally {
            con?.disconnect()
        }
        return null
    }

And post.php

<?php

$uploaddir = '/var/www/html/files/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);

if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
    echo "OK UPLOADED";
} else {
    echo "ERROR";
}
print_r($_FILES);


?>
Naoki Nakamura
  • 79
  • 1
  • 1
  • 7

1 Answers1

0

Finally, the code below works. I use multipart post solution. Now I think that kotlin's readBytes doesn't work properly with OutputDataStream , but I'm not sure about it...

private class UploadFileTask : AsyncTask<Void, Void, Void>() {
    override fun doInBackground(vararg params: Void): Void? {
        var con: HttpURLConnection? = null
        try {
            Log.i("POST", "Start POST")
            con = POST_URL.openConnection() as HttpURLConnection
            con.connectTimeout = 30 * 1000
            con.setRequestProperty("Accept-Charset", "UTF-8")
            con.setRequestProperty("ENCTYPE", "multipart/form-data")
            con.setRequestProperty("Connection", "Keep-Alive")
            con.setRequestProperty("Cache-Control", "no-cache")
            con.setRequestProperty("Content-Type", "multipart/form-data; boundary=$boundary")
            con.requestMethod = "POST"
            con.instanceFollowRedirects = false
            con.doInput = true
            con.doOutput = true
            val wavFile = File(wavPath)
            Log.i("POST", "exec post")

            con.connect()

            try {
                Log.i("POST", "Now writing to stream...")
                val outputStream = DataOutputStream(con.outputStream)
                outputStream.writeBytes(twoHyphens + boundary + lineEnd)
                outputStream.writeBytes("Content-Disposition: form-data; name=\"post\"; filename=\"${wavFile.name}\"$lineEnd")
                outputStream.writeBytes("Content-Type: application/octet-stream$lineEnd")
                outputStream.writeBytes("Content-Transfer-Encoding: binary$lineEnd")
                outputStream.writeBytes(lineEnd)
                val inputStream = FileInputStream(wavFile)
                inputStream.copyTo(outputStream)
                outputStream.writeBytes(lineEnd)
                outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd)
                outputStream.flush()
                outputStream.close()

            } catch (e: Exception) {
                Log.e("POST", "Exception occurred!")
            }
            val status = con.responseCode
            Log.i("STATUS", Integer.toString(status))

            when (status) {
                HttpURLConnection.HTTP_OK -> {
                    val inputStream = con.inputStream
                    val reader = BufferedReader(InputStreamReader(inputStream))
                    var httpSource = ""
                    var str = reader.readLine()
                    while (str != null) {
                        httpSource += str
                        str = reader.readLine()
                    }
                    Log.i("HTTPSOURCE", "source:$httpSource")
                    inputStream.close()
                }
                HttpURLConnection.HTTP_UNAUTHORIZED -> {
                    Log.e("POST", "UNAUTHORIZED")
                }
                else -> {
                    Log.i("POST", "CODE IS " + Integer.toString(status))
                }

            }

            con.disconnect()

        } catch (e: InterruptedException) {
            Log.e("UPLOADER", "aborting.")
        } finally {
            con?.disconnect()
        }
        return null
    }
}
Naoki Nakamura
  • 79
  • 1
  • 1
  • 7