Android与One Plus上的ESP8266的连接(Android 6.0.1) [英] Android connection with ESP8266 on One Plus ( Android 6.0.1)
问题描述
Android 6.0上的改装在连接到接入点后进行Http调用时出现问题
Retrofit on Android 6.0 has a problem making Http calls after connecting to Access Point
复制步骤:
- 连接到Esp8266接入点
- 对 http://192.168.4.1 进行http调用(esp8266访问点的默认网关) WIFI的IP地址为192.168.4.2
- 它引发以下异常
- Connect to Esp8266 Access Point
- Make an http call to http://192.168.4.1 (Default gateway of esp8266 accesspoint) The IP address of WIFI is 192.168.4.2
- It throws the below exception
我已经在Android 5.1上尝试过相同的功能,并且相同的代码也可以正常工作
I have tried the same on Android 5.1 and the same code works flawlessly
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:111) 在 okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187) 在 okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123) 在 okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java: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(Thread.java:818)
引起原因:android.system.ErrnoException:套接字失败:ENONET (机器不在网络上)
在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.newStream(StreamAllocation.java: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(Thread.java:818)
java.net.SocketException: socket failed: ENONET (Machine is not on the network)
at libcore.io.IoBridge.socket(IoBridge.java:619)
at java.net.PlainSocketImpl.create(PlainSocketImpl.java:198)
at java.net.Socket.checkOpenAndCreate(Socket.java:689)
at java.net.Socket.setSoTimeout(Socket.java:543)
at okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:183) at okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:170) at okhttp3.internal.io.RealConnection.connect(RealConnection.java:111) at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187) at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123) at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93) at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at okhttp3.RealCall.getResponse(RealCall.java:243)
at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163) at okhttp3.RealCall.access$100(RealCall.java:30)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818)
Caused by: android.system.ErrnoException: socket failed: ENONET (Machine is not on the network)
at libcore.io.Posix.socket(Native Method)
at libcore.io.BlockGuardOs.socket(BlockGuardOs.java:282)
at libcore.io.IoBridge.socket(IoBridge.java:604)
at java.net.PlainSocketImpl.create(PlainSocketImpl.java:198)
at java.net.Socket.checkOpenAndCreate(Socket.java:689)
at java.net.Socket.setSoTimeout(Socket.java:543) at okhttp3.internal.io.RealConnection.connectSocket(RealConnection.java:183) at okhttp3.internal.io.RealConnection.buildConnection(RealConnection.java:170) at okhttp3.internal.io.RealConnection.connect(RealConnection.java:111)
at okhttp3.internal.http.StreamAllocation.findConnection(StreamAllocation.java:187) at okhttp3.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:123) at okhttp3.internal.http.StreamAllocation.newStream(StreamAllocation.java:93) at okhttp3.internal.http.HttpEngine.connect(HttpEngine.java:296)
at okhttp3.internal.http.HttpEngine.sendRequest(HttpEngine.java:248) at okhttp3.RealCall.getResponse(RealCall.java:243) at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:201) at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:163)
at okhttp3.RealCall.access$100(RealCall.java:30)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:127)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588 at java.lang.Thread.run(Thread.java:818)
推荐答案
问题
错误ENONET
表示NetworkInfo.isConnected()
返回false
指示是否存在网络连接,并且可以 建立连接并传递数据. 尝试执行数据事务之前,请始终调用此方法.
Indicates whether network connectivity exists and it is possible to establish connections and pass data. Always call this before attempting to perform data transactions.
解决方案
产生一个守护进程线程,该线程等待Wifi网络(由ssid
提供)完全"连接(请参见上文),并使用true
(成功连接)或false
(超时)调用您的callback
或错误).
Solution
Spawn a daemon Thread which waits for the Wifi network (given by ssid
) to "fully" connect (see above) and call your callback
with either true
(successfully connected) or false
(timeout or error).
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
(运行时权限) ssid
must be enclosed in double quotation marks (seewifiConfiguration.SSID
)ConnectivityManager.getAllNetworks()
requires permissionACCESS_NETWORK_STATE
WifiManager.getConnectionInfo()
requires permissionsACCESS_NETWORK_STATE
andACCESS_COARSE_LOCATION
(runtime permission)
Notes
这篇关于Android与One Plus上的ESP8266的连接(Android 6.0.1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!