Android - модификация - параметры запроса отсутствуют в базовом URL - PullRequest
1 голос
/ 20 марта 2019

Я работаю над приложением для Android, используя Dagger2 + Retrofit + RxAndroid + OkHttp3 + Новые компоненты архитектуры. Мин. SDK = 16 .

Проблема: при запуске приложения в API 16 генерирование URL-адреса происходит некорректно. В URL отсутствуют параметры @QueryMap, которые я передаю через Retrofit. То же самое работает нормально, когда я тестирую приложение на уровне API 21+.

Правильный URL - на API 21+ - "http://api.apixu.com/v1/forecast.json?q=IDR&days=10&key=apikey"

URL, созданный на API 16/19 - "http://api.apixu.com/v1/forecast.json"

Модифицированный интерфейс -

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

Модифицированный строитель -

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

Прошло более 2 дней с тех пор, как я застрял в этом выпуске. Любая помощь будет оценена.

Обновление: Код запроса API работает на API 21+.

Ошибка API-16 и API-19.

Ответы [ 3 ]

1 голос
/ 20 марта 2019

Человек, прочитайте раздел Требования OkHttp: https://github.com/square/okhttp#requirements Буквально упоминается, что только ветка 3.12.x поддерживает Android 2.3+ (уровень API 9+) и Java 7+.Дуо было нехватать поддержки TLS 1.2 для устройства

1 голос
/ 20 марта 2019

Очевидно, что ваш URL не был закодирован, для этого вам необходимо убедиться, что он закодирован на всех платформах с использованием @QueryMap(encoded = true).

Если он не будет успешнымБоюсь, что вам нужно сделать это вручную, используя пользовательский перехватчик для кодирования таких символов, как ?, что равно %3F, например:

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

Ссылки:

0 голосов
/ 20 марта 2019

Наконец !! Я решил проблему. Решение - хитрость заключалась в использовании Interceptor. С проверками правильной версии SDK и перехватчиком, наконец, я запустил свою вещь.

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 требуется проверка SDK_VERSION -

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

Так что улов здесь для меня был - @QueryMap (в модификации) работал нормально, чтобы построить URL для SDK-21 +. Для SDK <21 я использовал перехватчик, как упомянуто выше, для построения URL. </p>

Я благодарю всех за помощь в этом вопросе. Я верю, что кто-то найдет это полезным !!

...