移动数据打开时通过wifi(无互联网)发送数据

hyg*_*ujo 9 sockets android android-networking android-wifi network-interface

我正在开发和通过wifi(由设备生成)连接到硬件设备并通过套接字连接向其发送数据的应用程序.问题是,当移动数据(3G/4G)被激活时,android会尝试通过它发送数据而不是通过设备生成的wifi发送数据,因为因为wifi没有互联网连接.我正在考虑使用ConnectivityManager#setNetworkPreference(),但它在api 21中已被弃用.

如何设置它使用设备生成的wifi而不是移动数据接口发送数据?

hyg*_*ujo 14

经过大量的研究和时间试图理解这一切后,我发现这在Android 5.0(Lollipop)之前的版本中是不可能的,操作系统一次只保留一个网络接口而且应用程序没有控制权在此.

所以要在大于或等于Lollipop的版本上执行此操作,我执行了以下操作:

  1. 在进行套接字连接之前,检查android是否大于或等于Lollipop,如果不是你只是做你必须正常做的事情;
  2. 如果版本与Lollipop相同或更高,您需要执行以下操作:

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
        final ConnectivityManager manager = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkRequest.Builder builder;
        builder = new NetworkRequest.Builder();
        //set the transport type do WIFI
        builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
        manager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    manager.bindProcessToNetwork(network);
                } else {
                    //This method was deprecated in API level 23
                    ConnectivityManager.setProcessDefaultNetwork(network);
                }
                try {
                    //do a callback or something else to alert your code that it's ok to send the message through socket now
                } catch (Exception e) {
                    e.printStackTrace();
                }
                manager.unregisterNetworkCallback(this);
            }
        });
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 完成后,您应该停止使用以下方法绑定进程:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        ConnectivityManager manager = (ConnectivityManager) InovePlugApplication.getContext()
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        manager.bindProcessToNetwork(null);
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ConnectivityManager.setProcessDefaultNetwork(null);
    }
    
    Run Code Online (Sandbox Code Playgroud)

这个答案帮助我理解了如何做到这一点/sf/answers/2088634621/.