Android与One Plus上的ESP8266的连接(Android 6.0.1) [英] Android connection with ESP8266 on One Plus ( Android 6.0.1)

查看:154
本文介绍了Android与One Plus上的ESP8266的连接(Android 6.0.1)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Android 6.0上的改装在连接到接入点后进行Http调用时出现问题

Retrofit on Android 6.0 has a problem making Http calls after connecting to Access Point

复制步骤:

  1. 连接到Esp8266接入点
  2. http://192.168.4.1 进行http调用(esp8266访问点的默认网关) WIFI的IP地址为192.168.4.2
  3. 它引发以下异常
  1. Connect to Esp8266 Access Point
  2. 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
  3. 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_STATEACCESS_COARSE_LOCATION(运行时权限)
  • Notes

    • ssid must be enclosed in double quotation marks (see wifiConfiguration.SSID)
    • ConnectivityManager.getAllNetworks() requires permission ACCESS_NETWORK_STATE
    • WifiManager.getConnectionInfo() requires permissions ACCESS_NETWORK_STATE and ACCESS_COARSE_LOCATION (runtime permission)
    • 这篇关于Android与One Plus上的ESP8266的连接(Android 6.0.1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆