java - Android 9 - 启用移动数据时套接字连接超时

标签 java android sockets android-wifi android-9.0-pie

我部署的应用程序在 Android 9 上失败。其部分功能是通过接入点网络配置模块,以允许该模块连接到用户的家庭网络。

我有代码可以检测并连接到正确的 WIFI 网络,但是当我尝试打开设备的套接字时,它会失败 - 仅在 Android 9 上且仅在启用移动数据的情况下。如果我手动禁用设备上的移动数据,一切都会正常运行。

Socket open() {
    Socket sock = new Socket(Proxy.NO_PROXY);
    try {
        sock.bind(new InetSocketAddress(localIpAddress(), 50000));
    } catch (IOException e) {
        activity.logContent("Warning: Failed to bind socket : " + e.toString());
    }
    try {
        sock.connect(new InetSocketAddress("192.168.17.1", 5555), (int)5000);
    } catch (IOException e) {
        // This catch fires when Mobile Data is on.
        activity.logContent("Connected to " + activity.mWifiManager.getConnectionInfo().getSSID());
        activity.logContent("Couldn't open socket : " + e.toString());
    }
    return sock;
}

我已经尝试过使用和不使用 Proxy.NO_PROXY 以及使用和不使用 bind() 调用。如果缺少绑定(bind)调用,则该错误意味着套接字正在尝试通过蜂窝网络进行连接。 (注意:activity.logContent() 是屏幕日志,因此在未连接到调试器时更容易查看发生的情况)。

知道出了什么问题吗?

最佳答案

经过几天的咒骂,我相信我已经找到了问题所在,从而找到了解决方案:

问题的发生是由于 android 版本的一些变化(我推测是 9.0,即使 API 21 上发生了其他变化),特别是在创建套接字时,如果系统检测到存在“更好的”网络(访问互联网、高信号等)套接字创建指的是该网络,而不是您想要的 wifi 网络。

我寻找方法强制在 wifi 网络(这是我想要的网络)上创建套接字,我发现的唯一方法是:

简单地说,而不是:

Socket sock = new Socket();

做:

ConnectivityManager connectivity = (ConnectivityManager) MyApp.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
                if (connectivity != null)
                {
                    for (Network network : connectivity.getAllNetworks())
                    {
                        NetworkInfo networkInfo = connectivity.getNetworkInfo(network);

                        if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI)
                        {
                            if (networkInfo.isConnected())
                            {
                                Socket sock =  network.getSocketFactory().createSocket();
                            }
                        }
                    }
            }

实际上浏览设备中存在的网络,当您找到 Activity 的 WiFi 时,您什么也不做,只需利用此功能来确保获得正确的套接字:

getSocketFactory().createSocket()

现在你有了工作套接字!

就我而言,它现在工作得很好,如果有人找到更好的解决方案,我们会很欢迎,但目前这是我发现的让一切像以前版本的 android 一样工作的唯一方法。

关于java - Android 9 - 启用移动数据时套接字连接超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56066632/

相关文章:

Java:我们如何在 "function pointer is prohibited"时创建回调函数?

java - LWJGL glTranslate 做奇怪的事情

Android 小部件 - 使用带有远程 View 的 setOnClickPendingIntent 未收到 Intent

c - 为什么不能将 linux 服务绑定(bind)到环回?

java - 是否有 : java. lang.RuntimeException 的解决方法:无法生成 DH key 对

java - Eclipse 中的 gradle 未加载 axis2 1.7.0

android - 在android中动态添加图库图片

java - 为什么 FirebaseInstanceIdService 服务在 Firebase 新更新中丢失了?

c - docker 环境中不支持的系列套接字失败

c - C:如何阅读网页