2

I am developing android application in which i send data to server using cronet now i want to send data to server in json object but not know how to send in object?

Following is my snippet code for GET method (WORKING).

Can anyone share how to use POST Method in android cronet ?

Dependencies

 implementation 'org.chromium.net:cronet-embedded:71.3578.98'

MainActivity

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import org.chromium.net.CronetEngine
import java.util.concurrent.Executors

class MainActivity : AppCompatActivity() {

    companion object {
        // Web page url
        private const val JSON_PLACEHOLDER_API_URL = "https://jsonplaceholder.typicode.com/todos/1"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Build a Cronet engine
        val cronetEngine =
            CronetEngine.Builder(this)
                .enableBrotli(true)
                .build()

        // Build the request
        val request =
            cronetEngine.newUrlRequestBuilder(
                JSON_PLACEHOLDER_API_URL,
                RequestCallback(),
                Executors.newSingleThreadExecutor()
            ).build()

        // Start the request
        request.start()
    }
}

RequestCallback

import android.util.Log
import org.chromium.net.CronetException
import org.chromium.net.UrlRequest
import org.chromium.net.UrlResponseInfo
import java.nio.ByteBuffer
import java.nio.charset.Charset


/**
 * Different methods are invoked for different response status
 */

class RequestCallback : UrlRequest.Callback() {

    companion object {
        // Log cat tag
        private val TAG = RequestCallback::class.java.simpleName
    }

    override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
        Log.i(TAG, "Response Started")
        val statusCode = info?.httpStatusCode
        Log.i(TAG, "Status Code $statusCode")
        if (statusCode == 200) {
            // Read the buffer
            request?.read(ByteBuffer.allocateDirect(32 * 1024))
        }
    }

    override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
        Log.i(TAG, "Response Completed")

        // Flip the buffer
        byteBuffer?.flip()

        // Convert the byte buffer to a string
        byteBuffer?.let {
            val byteArray = ByteArray(it.remaining())
            it.get(byteArray)
            String(byteArray, Charset.forName("UTF-8"))
        }.apply {
            Log.d(TAG, "Response: $this")
        }

        // Clear the buffer
        byteBuffer?.clear()

        // Read the buffer
        request?.read(byteBuffer)
    }

    override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
        Log.e(TAG, "Response Failed: ${error?.message}")
    }

    override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
        Log.i(TAG, "Response Succeeded")
    }

    override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
        Log.i(TAG, "Response Redirect to $newLocationUrl")
        request?.followRedirect()
    }

    override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
        super.onCanceled(request, info)
        Log.i(TAG, "Response cancelled")
    }
}

Output

Response: {
      "userId": 1,
      "id": 1,
      "title": "delectus aut autem",
      "completed": false
    }
Bolt UIX
  • 5,988
  • 6
  • 31
  • 58
  • Do you really need to use Cronet? If not I'd recommend using Retrofit as you will find many tutorials that will help you. – Ivan Wooll Mar 05 '20 at 09:22
  • In my project, i supposed to use google libraries only. Volley & retrofit have common issue. I am facing in my project double post sometime when I have slow request – Bolt UIX Mar 05 '20 at 09:57
  • Use wcf restfull services . You could write a wcf restfull for example in visual studio with every language supported in visual studio and call it in your android project.The returning result is a json(or xml) and in json format returning you must define the same class in java. This is very simple and easy. – maniaq Mar 05 '20 at 10:21

1 Answers1

3

Example:

    val myBuilder = CronetEngine.Builder(context)
    // Enable caching of HTTP data and
    // other information like QUIC server information, HTTP/2 protocol and QUIC protocol.
    val cronetEngine: CronetEngine = myBuilder
        .enableHttpCache(CronetEngine.Builder.HTTP_CACHE_IN_MEMORY, 100 * 1024.toLong())
        .enableHttp2(true)
        .enableQuic(true)
        .build()
    val executor: Executor = Executors.newSingleThreadExecutor()
    val requestBuilder = cronetEngine.newUrlRequestBuilder(
        "FULL-URL",
        MyUrlRequestCallback(),
        executor
    )
    // Content-Type is required, removing it will cause Exception
    requestBuilder.addHeader("Content-Type","application/json; charset=UTF-8")
    requestBuilder.setHttpMethod("POST")
    val myUploadDataProvider = MyUploadDataProvider()
    requestBuilder.setUploadDataProvider(myUploadDataProvider,executor)
    val request: UrlRequest = requestBuilder.build()
    request.start()

MyUploadDataProvider Class:

import android.util.Log
import org.chromium.net.UploadDataProvider
import org.chromium.net.UploadDataSink
import java.lang.Exception
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets

private const val TAG = "MyUploadDataProvider"
//TODO replace username and passowrd "_user & _pass"
var string: String ="{\"username\":\"_user\",\"password\":\"_pass\"}"
val charset = StandardCharsets.UTF_8

class MyUploadDataProvider() : UploadDataProvider() {

    override fun getLength(): Long {
    val size:Long = string.length.toLong()
    Log.e(TAG,"Length = "+size)
    return size
    }

    override fun rewind(uploadDataSink: UploadDataSink?) {
    Log.e(TAG,"REWIND IS CALLED")
    uploadDataSink!!.onRewindSucceeded()
    }

    override fun read(uploadDataSink: UploadDataSink?, byteBuffer: ByteBuffer?) {
    Log.e(TAG,"READ IS CALLED")
    byteBuffer!!.put(string.toByteArray(charset))
    //byteBuffer.rewind()
    //For chunked uploads, true if this is the final read. It must be false for non-chunked uploads.
    uploadDataSink!!.onReadSucceeded(false)
    }

}