Соединение Android с ESP8266 на One Plus ( Android 6.0.1)
Retrofit на Android 6.0 имеет проблемы с выполнением Http-вызовов после подключения к точке доступа
Действия по воспроизведению:
- Подключение к точке доступа Esp8266
- Выполните вызов http на http://192.168.4.1/ (шлюз по умолчанию точки доступа esp8266). IP-адрес WIFI - 192.168.4.2.
- Выкидывает приведенное ниже исключение
Я попробовал то же самое на 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
(разрешение во время выполнения)