Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

API call on Android 19 emulator : isConnected failed: EHOSTUNREACH (No route to host)

I'm retrieving data from an API. When I try to launch the app on an Android emulator running Android API 19 the request fails with the error below. It work perfectly fine using other versions of the emulator (like Android API 27).

I changed the URL to target another API from a previous project and it works. So it seems the issue is with this specific API but I don't understand why, especially as when I pass the URL into the emulator's browser it works fine.

I've seen some people suggesting this is an issue with the computer's firewall, but there is no firewall enabled on mine.

Retrofit

interface SpaceXApi {
    @GET("rockets")
    fun getRockets(): Observable<MutableList<RocketDto>>
}

object SpaceXApiConstants {
    const val BASE_URL = "https://api.spacexdata.com/v3/"
}

// Interceptor passed to OkHttpClient Builder
class ConnectivityInterceptor(private val context: Context) : Interceptor {

    override fun intercept(chain: Interceptor.Chain): Response {
        if (isConnected()) {
            return chain.proceed(chain.request())
        } else {
            throw NoNetworkException()
        }
    }
}

Error

D/OkHttp: --> GET https://api.spacexdata.com/v3/rockets
D/OkHttp: <-- HTTP FAILED: java.net.ConnectException: Failed to connect to api.spacexdata.com/2606:4700:30::681f:5749:443
W/System.err: java.net.ConnectException: Failed to connect to api.spacexdata.com/2606:4700:30::681f:5749:443
        at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:247)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:165)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:213)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at com.example.myproject.network.ConnectivityInterceptor.intercept(ConnectivityInterceptor.kt:13)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
        at okhttp3.RealCall.execute(RealCall.java:77)
        at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
        at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:42)
        at io.reactivex.Observable.subscribe(Observable.java:12090)
        at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
        at io.reactivex.Observable.subscribe(Observable.java:12090)
        at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
        at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
        at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
        at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
        at java.lang.Thread.run(Thread.java:841)
    Caused by: java.net.ConnectException: failed to connect to api.spacexdata.com/2606:4700:30::681f:5749 (port 443) after 20000ms: isConnected failed: EHOSTUNREACH (No route to host)
        at libcore.io.IoBridge.isConnected(IoBridge.java:223)
        at libcore.io.IoBridge.connectErrno(IoBridge.java:161)
12-02 17:44:40.445 4877-4877/com.example.myproject W/System.err:     at libcore.io.IoBridge.connect(IoBridge.java:112)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
        at java.net.Socket.connect(Socket.java:843)
        at okhttp3.internal.platform.AndroidPlatform.connectSocket(AndroidPlatform.java:73)
        at okhttp3.internal.connection.RealConnection.connectSocket(RealConnection.java:245)
        ... 38 more
    Caused by: libcore.io.ErrnoException: isConnected failed: EHOSTUNREACH (No route to host)
        at libcore.io.IoBridge.isConnected(IoBridge.java:208)
        ... 45 more

Any solution?

like image 440
Eselfar Avatar asked Dec 02 '18 17:12

Eselfar


1 Answers

Looks like a protocol issue : devices with API 19 and older don't use TLS 1.2 by default. You can enable it with this :

ProviderInstaller.installIfNeededAsync(this, new ProviderInstaller.ProviderInstallListener() {
            @Override
            public void onProviderInstalled() {
            }
            @Override
            public void onProviderInstallFailed(int i, Intent intent) {
                Log.i(TAG, "Provider install failed (" + i + ") : SSL Problems may occurs");
            }
        });

This has to be called before your first call, so I usually call it in the OnCreate of the Application object.

For more information, you can check this link : https://quizlet.com/blog/working-with-tls-1-2-on-android-4-4-and-lower

like image 169
E. Morice Avatar answered Sep 24 '22 21:09

E. Morice