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
}
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)
}
}