Android连接与一个Plus上的ESP8266(Android 6.0.1)

Android连接与一个Plus上的ESP8266(Android 6.0.1),android,retrofit,retrofit2,esp8266,okhttp,Android,Retrofit,Retrofit2,Esp8266,Okhttp,安卓6.0上的改型在连接到接入点后进行Http调用时出现问题 复制步骤: 连接到Esp8266接入点 对(esp8266 accesspoint的默认网关)进行http调用 WIFI的IP地址为192.168.4.2 它抛出以下异常 我在安卓5.1上也尝试过同样的方法,同样的代码可以完美地工作 java.net.SocketException:socket失败:ENONET(计算机不在网络上) 位于libcore.io.IoBridge.socket(IoBridge.java:619) 在ja

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

复制步骤:

  • 连接到Esp8266接入点
  • 对(esp8266 accesspoint的默认网关)进行http调用 WIFI的IP地址为192.168.4.2
  • 它抛出以下异常
  • 我在安卓5.1上也尝试过同样的方法,同样的代码可以完美地工作

    java.net.SocketException:socket失败: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.procedure(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.setSortimeout(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.procedure(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 运行(Thread.java:818)

    问题 错误
    ENONET
    表示
    NetworkInfo.isConnected()
    返回
    false

    指示是否存在网络连接以及是否可以 建立连接并传递数据。 在尝试执行数据事务之前,请始终调用此函数

    解决方案 生成一个守护进程线程,该线程等待Wifi网络(由
    ssid
    给出)进行“完全”连接(见上文),并使用
    true
    (成功连接)或
    false
    (超时或错误)调用您的
    回调

    实施
    private ConnectivityManager connectivity=。。。;
    私人WifiManager wifi=。。。;
    私有void waitForWifi(最终字符串ssid,最终消费者回调){
    最终螺纹=新螺纹(()->{
    对于(int i=0;i<300;i++){
    最终WifiInfo=wifi.getConnectionInfo();
    NetworkInfo NetworkInfo=null;
    对于(最终网络:connectivity.getAllNetworks()){
    最终网络能力=连接性。getNetworkCapabilities(网络);
    if(能力.hasTransport(网络能力.TRANSPORT\u WIFI)){
    networkInfo=connectivity.getNetworkInfo(网络);
    打破
    }
    }
    如果(info!=null&&info.ssid==ssid&&networkInfo!=null&&networkInfo.isConnected()){
    callback.accept(true);
    返回;
    }
    睡眠(100);
    }
    callback.accept(false);
    });
    setDaemon(true);
    thread.start();
    }
    
    笔记
    • ssid
      必须用双引号括起来(请参见
      wifiConfiguration.ssid
    • ConnectivityManager.getAllNetworks()
      需要访问网络状态的权限
    • WifiManager.getConnectionInfo()
      需要权限
      访问网络状态
      访问位置
      (运行时权限)
    ENONET(机器不在网络上)
    可能有几个原因。最可能的原因是您尝试过早进行套接字连接,即。
    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();
    }