1
votes

Android - retrofit - Paramètres de requête manquants dans l'URL de base

Je travaille sur une application Android utilisant Dagger2 + Retrofit + RxAndroid + OkHttp3 + Nouveaux composants d'architecture. Min sdk = 16 .

Problème: lors de l'exécution de l'application sur l'API 16, la génération d'URL n'est pas correcte. L'URL ne contient pas les paramètres @QueryMap que je transmets via Retrofit. La même chose fonctionne bien lorsque je teste l'application sur les niveaux API 21+.

URL correcte - sur api 21+ - " http: //api.apixu. com / v1 / Forecast.json? q = IDR & days = 10 & key = apikey "

URL générée sur l'api 16/19 -" http://api.apixu.com/v1/forecast.json "

Interface de mise à niveau -

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

Retrofit Builder -

val httpClient = getOkHttpClient()
    return Retrofit.Builder()
        .baseUrl(apiBaseUrl)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .client(httpClient)
        .build()

OkHttpClient -

@GET("forecast.json")
fun fetchWeatherDetails(
    @QueryMap hashMap: @NotNull HashMap<String, String>
): @NotNull Observable<ApiResponse>

Cela fait plus de 2 jours puisque je suis coincé dans ce numéro. Toute aide serait appréciée.

Mise à jour: Le code de requête Api fonctionne correctement sur l'API 21+.

Échec sur l'API-16 et l'API-19.


2 commentaires

Votre problème est étrange, je ne peux rien dire d'autre qu'une suggestion, essayez d'utiliser une requête plutôt que QueryMap. Peut résoudre votre problème.


A essayé. Avec @Query - Même problème. Une fois passé l'URL entière - cela fonctionnait bien. Le problème que je crois est simple - l'url est analysée sur api23 + mais pas sur api 16. Je me demandais si cela avait quelque chose à voir avec la compatibilité descendante pour le niveau 16 de l'API.


3 Réponses :


1
votes

Il est évident que votre URL n'a pas été encodée, pour ce faire, vous devez vous assurer qu'elle est encodée sur toutes les plates-formes en utilisant @QueryMap (encoded = true) .

Si cela ne réussit pas, je crains que vous deviez le faire manuellement en utilisant un intercepteur personnalisé pour encoder des caractères tels que ? qui équivaut à % 3F , par exemple:

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

Références:


2 commentaires

Alors, pourquoi fonctionne-t-il au niveau de l'API 23+ et non au niveau de l'API 16? Telle est la question principale. La mise à niveau interroge correctement l'URL et affiche les résultats comme prévu dans api23 +. Mais quand je l'exécute sur api16 -> donne une erreur. Et dans le journal, je peux voir que l'url qui est interrogée n'est pas analysée correctement.


@PranavBhoraskar Je crois qu'il y a une baisse de support 16+ c'est-à-dire: des annotations ou certaines API externes, qui seront difficiles à corriger avec l'existence de l'API 29 .



1
votes

Homme, lisez la section Exigences d'OkHttp: https://github.com/square/okhttp#requirements Il mentionne littéralement que la branche 3.12.x prend en charge Android 2.3+ (niveau d'API 9+) et Java 7+. C'était duo de ne pas prendre en charge TLS 1.2 pour le périphérique


0 commentaires

0
votes

Enfin !! J'ai résolu le problème. Solution - L'astuce était d'utiliser Interceptor. Avec des vérifications de la VERSION correcte du SDK et de l'intercepteur, j'ai enfin mis mon truc en marche.

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
   builder.addInterceptor(HeaderInterceptor())
}

OkHttpClient avait besoin d'une vérification SDK_VERSION -

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

Alors, cliquez ici pour moi était - @QueryMap (en rénovation) a bien fonctionné pour créer l'URL du SDK-21 +. Pour les SDK

Je vous remercie tous pour l'aide apportée à ce sujet. Je crois que quelqu'un trouverait cela utile !!


0 commentaires