Соединение Android с ESP8266 на One Plus ( Android 6.0.1)

Retrofit на Android 6.0 имеет проблемы с выполнением Http-вызовов после подключения к точке доступа

Действия по воспроизведению:

  1. Подключение к точке доступа Esp8266
  2. Выполните вызов http на http://192.168.4.1/ (шлюз по умолчанию точки доступа esp8266). IP-адрес WIFI - 192.168.4.2.
  3. Выкидывает приведенное ниже исключение

Я попробовал то же самое на Android 5.1 и тот же код работает без нареканий

java.net.SocketException: сокет не выполнен: ENONET (компьютер не находится в сети)
в libcore.io.IoBridge.socket(IoBridge.java:619)
в java.net.PlainSocketImpl.create(PlainSocketImpl.java:198)
на java.net.Socket.checkOpenAndCreate(Socket.java:689)
на java.net.Socket.setSoTimeout(Socket.java:543)
на okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:183) на okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:170) на okhttp3.internal.io.RealConnection.connect (RealConnection.java:11:) в okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187) в okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123) в okhttp3.internal.http.nloc.llocAllocAloc 93) на сайте okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296).
на okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
на okhttp3.RealCall.getResponse(RealCall.java:243)
в okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201) в okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163) в okhttp3.RealCall.access$100(RealCall.java:30)
на okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
в okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
в java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113 в java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) в java.lang.Thread.run(18).
Вызвано: android.system.ErrnoException: сокет не выполнен: ENONET (компьютер не находится в сети)
at libcore.io.Posix.socket (собственный метод)
в libcore.io.BlockGuardOs.socket(BlockGuardOs.java:282)
в libcore.io.IoBridge.socket(IoBridge.java:604)
в java.net.PlainSocketImpl.create(PlainSocketImpl.java:198)
на java.net.Socket.checkOpenAndCreate(Socket.java:689)
на java.net.Socket.setSoTimeout(Socket.java:543) на okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:183) на okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:170) на okhttp3.internal.io.RealConnection.connect (RealConnection.java:111)
по адресу okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187) по адресу okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123) по адресу okhttp3.internal.http.StreamAllocation) на okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
по адресу okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248) по адресу okhttp3.RealCall.getResponse(RealCall.java:243) по адресу okhttp3.RealCall $ ApplicationInterceptorChain.proceed (RealCall.Receed: Real2010). getResponseWithInterceptorChain (RealCall.java:163)
на okhttp3.RealCall.access$100(RealCall.java:30)
на okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
в okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
в java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113 в java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:588 в java.lang.Thread.run(Thread.j)

1 ответ

проблема

ошибка ENONET Значит это NetworkInfo.isConnected() возвращается false

Указывает, существует ли сетевое соединение, и возможно ли устанавливать соединения и передавать данные. Всегда вызывайте это, прежде чем пытаться выполнить транзакции данных.

Решение

Создайте поток демона, который ожидает сеть Wi-Fi (предоставленный ssid) "полностью" подключиться (см. выше) и позвонить callback либо с true (успешно подключен) или false (таймаут или ошибка).

Реализация

private ConnectivityManager connectivity = ...;
private WifiManager wifi = ...;

private void waitForWifi(final String ssid, final Consumer<Boolean> callback) {
    final Thread thread = new Thread(() -> {
        for (int i = 0; i < 300; i++) {
            final WifiInfo info = wifi.getConnectionInfo();
            NetworkInfo networkInfo = null;

            for (final Network network : connectivity.getAllNetworks()) {
                final NetworkCapabilities capabilities = connectivity.getNetworkCapabilities(network);

                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    networkInfo = connectivity.getNetworkInfo(network);
                    break;
                }
            }

            if (info != null && info.ssid == ssid && networkInfo != null && networkInfo.isConnected()) {
                callback.accept(true);
                return;
            }

            Thread.sleep(100);
        }

        callback.accept(false);
    });

    thread.setDaemon(true);
    thread.start();
}

Заметки

  • ssid должны быть заключены в двойные кавычки (см. wifiConfiguration.SSID)
  • ConnectivityManager.getAllNetworks() требуется разрешение ACCESS_NETWORK_STATE
  • WifiManager.getConnectionInfo() требуются разрешения ACCESS_NETWORK_STATE а также ACCESS_COARSE_LOCATION (разрешение во время выполнения)
Другие вопросы по тегам