I am using CronetEngine for making a network request as below
val engine: CronetEngine = CronetEngine.Builder(context).enableQuic(false)
.enableBrotli(true)
.enableHttp2(false).build()
val callFactory: Call.Factory = CronetCallFactory.newBuilder(engine).build()
And calling the result as
request = Request.Builder()
.url(url)
.post(formBody.build())
.headers(headers)
.build()
callFactory.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
}
override fun onResponse(call: Call, response: Response) {
result = response.body?.string()
mResponseCode = response.code
mResponseHeader = response.headers.toMultimap()
}
})
I am getting the response in compressed format.
Where as I want it in plain text or decompressed format.
Any configuration I am missing here?
Related
I am trying to fetch phot with Microsoft graph API and I am able to get successful result.
API : "https://graph.microsoft.com/v1.0/users/{UPN}/photo//$value"
code :
try {
val client = OkHttpClient()
val mediaType: MediaType? = "image/jpeg".toMediaTypeOrNull()
val JSON: MediaType? = "application/json; charset=utf-8".toMediaTypeOrNull()
val json = ""
val request: Request = Request.Builder()
.url("https://graph.microsoft.com/v1.0/users/{UPN}/photo/"+"$"+"value")
.get()
.addHeader("Content-Type", "image/jpeg")
.addHeader(
"Authorization",
token
)
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
response.use {
if (!response.isSuccessful) throw IOException("Unexpected code $response")
for ((name, value) in response.headers) {
println("$name: $value")
}
Log.d("ProfilePhoto","ProfilePhoto"+response.body!!.toString())
Log.d("ProfilePhoto","ProfilePhoto"+response.body!!.toString().toMediaTypeOrNull())
response.body?.charStream()?.readText()?.let {
//Where it refers to Response string
val bufferedInputStream = BufferedInputStream(response.body!!.byteStream())
val image = BitmapFactory.decodeStream(bufferedInputStream)
Log.d(
"ProfilePhoto",
"Success response from ProfilePhoto Media " + response.body!!.contentType()
)
Log.d(
"ProfilePhoto",
"Success response from ProfilePhoto" + it.toString()
)
}
} else {
TODO("VERSION.SDK_INT < O")
}
}
}
})
}catch(err : Error){
Log.d(
"ProfilePhoto",
"Error response from ProfilePhoto" + err
)
}
As you can see I am trying to convert response to Bitmap but it is returning null!
I am new to kotlin and all I can understand is that response is binary data and content type of responce is image/jpeg. How can I convert this to Bitmap or Image that I can show on my Imageview.
Reponse : ������JFIF��������������C� $.' ",#(7),01444'9=82<.342����C 2!!22222222222222222222222222222222222222222222222222������"�������������������������� �����������}��!1AQa"q2��#B��R��$3br� %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz������������������������������������������������������������������������������������������� ���������w��!1AQaq"2B���� #3R�br� $4�%�&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz��������������������������������������������������������������������������������?���_xkA�º<�h�k��B��i$�$�?������t����(���:/�xA����ֵ�'�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#-3��������� ֢�2�����������(����_����?�?�j('��L����8����E�=���#-3��������� ֢�2�����������(����_����?�?�j('��L����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�2������t����(����[��������?�j('�o�K����8����E�=���#/��������� ֢�<�֑�Y���;m:�6(�b�T���Uό�7Zׂ��(�Y���:/�xA����ֵ�'���(�����Z֠�(��(��(��(��(��(��(��(����Yi���w �������,�t�f�x�`
Have you tried by decoding into Base64 ,you can use the java.util.Base64 library to encode and decode strings in Kotlin.
First, let’s use the encoder to encode , “Baeldung” string, please check the sample code below
val originalString = "Baeldung"
val encodedString: String = Base64.getEncoder().encodeToString(originalString.toByteArray())
assertEquals("QmFlbGR1bmc=", encodedString)
Git - https://github.com/Baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-strings
I am attempting to make a sync call that needs to complete before proceeding with storing a user in the cloud. I believe the issue is within the RequestBody as it looks like it is just a byte array. Below is the code:
val client = OkHttpClient()
val mediaType: MediaType? = "application/json".toMediaTypeOrNull()
val body: RequestBody =
RequestBody.create(mediaType, "{\"type\":\"DEFAULT\",\"name\":\"lkjlkj\"}")
val request: Request = okhttp3.Request.Builder()
.url("https://api.example.com/endpoint")
.post(body)
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json")
.addHeader(
"Authorization",
"Bearer SK-xxxxxx-4QAXH"
)
.build()
Toast.makeText(this#RegisterActivity, "Entering Call",Toast.LENGTH_SHORT).show()
val response: Unit = client.newCall(request).execute().use {
Toast.makeText(this#RegisterActivity, "sent call, awaiting response",Toast.LENGTH_SHORT).show()
if (it.isSuccessful){
val content = JSONObject(it.body.toString())
desiredString = content.getJSONArray("desiredStringField").toString()
Toast.makeText(this#RegisterActivity, desiredString,Toast.LENGTH_SHORT).show()
}
if (!it.isSuccessful){
Toast.makeText(this#RegisterActivity, "failed",Toast.LENGTH_SHORT).show()
}
}
The code doesn't crash but it seems the call never completes, as it never makes it into the it.isSuccessful or !it.isSuccessful. Perhaps its a bad formed call somehow. Please help if you can.
Try to enqueue the request and manage the response using a Callback:
client.newCall(request).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
if (!response.isSuccessful){
Toast.makeText(this#RegisterActivity, "failed",Toast.LENGTH_SHORT).show()
return
}
try {
val content = JSONObject(response.body?.string() ?: "")
desiredString = content.getJSONArray("desiredStringField").toString()
Toast.makeText(this#RegisterActivity, desiredString,Toast.LENGTH_SHORT).show()
} catch (e: JSONException) {
// Error parsing JSON object
}
}
override fun onFailure(call: Call, e: IOException) {
Toast.makeText(this#RegisterActivity, "failed",Toast.LENGTH_SHORT).show()
}
}
I want to stream twitter tweets continuously with twitter stream api with retrofit and without any 3rd party libraries. When i try to call the api " https://api.twitter.com/2/tweets/search/stream " I'm only getting the result first time. How to stream it?
I have finally achieved it using this snippet
override suspend fun streamTweets(): Flow<Resource<TweetResponseModel>> {
return flow {
val client: OkHttpClient = OkHttpClient().newBuilder().addInterceptor(
BasicAuthInterceptor(getAPIKey(), getAPISecretKey())
).build()
val request: Request = Request.Builder()
.url(TWITTER_STREAM_URL)
.method("GET", null)
.build()
val response: okhttp3.Response = client.newCall(request).execute()
val source = response.body?.source()
val buffer = Buffer()
while (!source!!.exhausted()) {
response.body?.source()?.read(buffer, 8192)
val data = buffer.readString(Charset.defaultCharset())
try {
val tweetResponseModel: TweetResponseModel =
Gson().fromJson(data, TweetResponseModel::class.java)
emit(Resource.Success(tweetResponseModel))
} catch (e: Exception) {
Log.e("jsonException", data)
}
}
}.flowOn(ioDispatcher)
}
So I have this function created to generate fake values for my list:
private fun generateFakeValues(): List<Torrent> {
val values = mutableListOf<Torrent>()
val torrent1 = Torrent()
torrent1.name = "Big Buck Bunny"
torrent1.downloadSpeed = 0.00
torrent1.uploadSpeed = 0.00
torrent1.downloaded = 59.23
torrent1.length = 263.64
values.add((torrent1))
return values
}
And it works just fine. Now I added a Http request and wanted to parse the data but the items are not in the list:
private fun getTorrents(): List<Torrent> {
var torrents = mutableListOf<Torrent>()
val request = Request.Builder()
.url("...")
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
response.use {
if (!response.isSuccessful) {
throw IOException("Unexpected code $response")
}
torrents = gson.fromJson(response.body!!.string(), mutableListOf<Torrent>()::class.java)
}
}
})
return torrents
}
What am I doing wrong?
Since network call happens on background thread. You have to publish data to UI thread like
activity.runOnUiThread({/*add to adapter and notify data change to adapter*/})
or
view.post({/*add to adapter and notify data change to adapter*/})
I try to create kotlin app with OkHttp3. Can I use response.header("error") or response.header("success") in if()?
For example, if I got response with error I will show error or if I get success and I can start next activity to show in next activity header("username").
My request fun:
fun requestAuth(url: String) {
var param = FormBody.Builder()
.add("login", login.text.toString())
.add("password", password.text.toString())
.build()
val request = Request.Builder().url(url).post(param).build()
val client = OkHttpClient()
.newBuilder()
.build()
client.newCall(request).enqueue(object : Callback{
override fun onResponse(call: Call, response: Response) {
// startActivity(Intent(this#Login, NavigationMenu::class.java)
// .putExtra("session_token", response
// .header("session_token")
// .toString())
.putExtra("username", response.header("username").toString()))
}
Thank you for every suggestion