Troubles with OkHttpClient() POST not working KOTLIN - android

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

Related

Not getting plain text response using Cronet Engine with Brotli enabled

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?

Convert Binary data to Bitmap in Kotlin

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

Where i put decryption code for responce in retrofit andriod

I want to decrypt server data where can I decrypt it in android using retrofit
before using enc/dec I get this data from server
{
"success": true,
"secret": "NVARWBA4MAGSAW2F"
}
When I hit this API
#Headers("Content-Type: application/json")
#POST("user")
suspend fun addUser(#Body addUser: AddUser): Response<com.pryze.repository.model.User>
and after using enc/dec in response from server only I get encrypted text
'JAdS9hy168A2fG6FVTyzmFY739iawyk9qZ/yynRLtFTtE9nXxHyEas5ZrLzpl9IhpdgD27RpPBS5HsFHnVParg=='
and my app is crushed due to illegal response how can I solve this where I can put my dec code to first decrypt it then assign that to the response.
please try this code in your inspector class for Encryption and Decryption both.
override fun intercept(chain: Interceptor.Chain): Response {
if (!isInternetAvailable()){
throw NoInternetException("Make sure you have an active data connection")
}
try {
val aesUtil = AesUtil(keySize, iterationCount)
var request: Request = chain.request()
val buffer = Buffer()
request.body?.writeTo(buffer)
val strOldBody: String = buffer.readUtf8()
val encText = aesUtil.encrypt(salt,iv,passphrase,strOldBody)
val mediaType: MediaType? = "text/plain; charset=utf-8".toMediaTypeOrNull()
val strNewBody: String = encText
val body: RequestBody = RequestBody.create(mediaType, strNewBody)
request = request.newBuilder().addHeader("authorization", "Bearer " + t.getToken("JWT")).header("Content-Length", body.contentLength().toString()).method(request.method, body).build()
var req= chain.proceed(request)
var enc_data=""+req.body?.string().toString()
enc_data = aesUtil.decrypt(salt,iv,passphrase,enc_data)
return req.newBuilder().body(ResponseBody.create(req.body?.contentType(), enc_data)).build()
}
catch (e:ServiceConfigurationError){
}
catch (e: SSLHandshakeException){
throw NoInternetException("Request Time Out")
}
catch (e: ConnectException){
throw NoInternetException("Request Time Out")
}
catch (e: SocketTimeoutException){
throw NoInternetException("Make sure you have an active data connection")
}
catch (e:UnknownHostException){
throw NoInternetException("Make sure you have an active data connection")
}
catch (e: ErrnoException){
throw NoInternetException("Request Time Out")
}
throw NoInternetException("Request Time Out")
}

Can I use response in if () in kotlin?

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

How to create an interceptor for errors to make another call?

I'm getting a 401, because token has expired, so I need to renew the token with another call and then do the call again, is there an easy way instead of doing :
disposable = loginService.login(
UserToLoginRequest(
input_email_login.text.toString(),
input_password_login.text.toString(),
generateRandomDeviceInfo()
)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ result ->
//It works
},
{ error -> if(error.code == 401) renewAccessToken() }
)
The thing is that I want to do something like this guy : Refreshing Oath token, but if it's possible to call again the same endpoint with the same parameters.
Example
getApple(1) <-- return info of apple id 1
The result is 401 <-- can't do the call without refreshing the accessToken refreshAccessToken()
Automatically call getApple(1) without disturbing the user
class Inceptor : Interceptor {
internal var token: String?=null
#Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
var request=chain.request()
request=request.newBuilder().build()
val response=chain.proceed(request)
if (response.code() == HttpURLConnection.HTTP_UNAUTHORIZED) {
// get a new token (I use a synchronous Retrofit call)
val requestBody=FormBody.Builder()
.add("UserName", “abcd")
.add("Password", “*****")
.build()
val newRequest=request.newBuilder()
.url("Put your url")
.post(requestBody)
.build()
val tokenRefreshResponse=chain.proceed(newRequest)
val newRetryHttpUrl=request.url()
if (tokenRefreshResponse.code() == HttpURLConnection.HTTP_OK) {
val retryOriginaResponseBody: RequestBody
val builder=FormBody.Builder()
retryOriginaResponseBody=builder.build()
val retryRequest: Request
if (request.method() == "POST") {
retryRequest=request.newBuilder()
.url(request.url())
.post(retryOriginaResponseBody)
.build()
} else {
retryRequest=request.newBuilder()
.url(newRetryHttpUrl)
.build()
}
val retryResponse=chain.proceed(retryRequest)
return retryResponse
} else {
return tokenRefreshResponse
}
}
}
return response
}
}

Categories

Resources