Reputation: 135
I am working on an android app using Dagger2 + Retrofit + RxAndroid + OkHttp3 + New architecture components. Min sdk = 16.
Issue : When running the app on API 16, the Url generation is not correct. Url is missing the @QueryMap parameters I am passing via Retrofit. The same is working fine when I am testing the app on api levels 21+.
Correct url - on api 21+ - "http://api.apixu.com/v1/forecast.json?q=IDR&days=10&key=apikey"
url generated on api 16/19 - "http://api.apixu.com/v1/forecast.json"
Retrofit Interface -
@GET("forecast.json")
fun fetchWeatherDetails(
@QueryMap hashMap: @NotNull HashMap<String, String>
): @NotNull Observable<ApiResponse>
Retrofit Builder -
val httpClient = getOkHttpClient()
return Retrofit.Builder()
.baseUrl(apiBaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(httpClient)
.build()
OkHttpClient -
val builder = OkHttpClient.Builder()
builder
.cache(cache)
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.followRedirects(true)
.followSslRedirects(true)
val httpLoggingInterceptor = HttpLoggingInterceptor()
if (BuildConfig.DEBUG) {
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
} else {
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
}
builder.addInterceptor(HeaderInterceptor())
.addInterceptor(httpLoggingInterceptor)
return builder.build()
Its been more than 2 days since I am stuck in this issue. Any help would be appreciated.
Update : Api query Code is working fine on API 21+.
Failed on API-16 & API-19.
Upvotes: 1
Views: 2319
Reputation: 135
Finally!! I solved the issue. Solution - Trick was to use Interceptor. With checks for correct SDK VERSION and interceptor, finally I got my thing running.
internal class HeaderInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val url = request.url().newBuilder()
.addQueryParameter("key", API_KEY)
.addQueryParameter("q", QUERY_PARAMETER)
.addQueryParameter("days", DAYS)
.build()
request = request.newBuilder().url(url).build()
return chain.proceed(request)
}
}
OkHttpClient needed SDK_VERSION check -
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
builder.addInterceptor(HeaderInterceptor())
}
So catch here for me was - @QueryMap(in retrofit) worked fine to build the url for SDK-21+. For SDKs<21 I used interceptor as mentioned above for building the url.
I thank you all for the help on this matter. I believe someone out there would find this helpful!!
Upvotes: 0
Reputation: 11
Man, read the OkHttp Requirements section: https://github.com/square/okhttp#requirements It literally mentions only 3.12.x branch supports Android 2.3+ (API level 9+) and Java 7+. It was duo to lack support for TLS 1.2 for device < API 21. If you really wanna support anything that under API 21 then update your OkHttp version to 3.12.x which will be still available til December 31, 2020.
Upvotes: 1
Reputation: 1297
It's obvious that your URL didn't encoded, to do so you need to insure that it's get encoded on all platforms using @QueryMap(encoded = true)
.
If it doesn't success I'm afraid that you need to do that manually using custom interceptor to encode such characters like ?
which equal to %3F
, e.g:
@Override
Response intercept(Interceptor.Chain chain) throws IOException {
Request request = chain.request()
def string = request.url().toString()
string = string.replace("%26", "&")
string = string.replace("%3D", "=")
string = string.replace("%3F", "?")
Request newRequest = new Request.Builder()
.url(string)
.build()
return chain.proceed(newRequest)
}
References:
Upvotes: 1