在wifi开启时,强制通过手机网络发送请求

                                在wifi开启时,强制通过手机网络发送请求

须知

1.  Android 5.0(LOLLIPOP)以上,在同一时间下,Android系统则可以允许多网络类型连接,在这样子的前提下,你就可以选择究竟采用那种网络来完成你的请求。在Android 5.0(LOLLIPOP)之前,在同一时间下,Android系统只能允许一种网络类型连接,所以只支持5.0以上系统。

2.  部分机型可能受定制限制,网络强制切换不了。

3.  调用requestNetwork方法,并没有像官网描述那样,立即采用移动网络进行请求,而是在我手动关闭wifi之后,系统切换到移动网络的时候才会请求。所以尽量使用registerNetworkCallback方法。

具体实现

通过以下几步动态选择和连接网络:

  1. 创建 ConnectivityManager
  2. 创建android.net.NetworkRequest对指定的网络和传输需要类型。
  3. 搜索合适的网络,调用 ConnectivityManager.requestNetwork()或者ConnectivityManager.registerNetworkCallback(),传入NetworkRequest 和实现ConnectivityManager.NetworkCallbackListener接口。
  4. 当系统查出一个合适网络时。就会连接该网络,回调NetworkCallbackListener.onAvailable(),回调中获取android.net.Network对象,调用ConnectivityManager.bindProcessToNetwork(Network)方法(API小于23调用ConnectivityManager. setProcessDefaultNetwork(Network))强制设置数据网络。

关键代码

private void selectNetwork() {
        if (Build.VERSION.SDK_INT >= 21) {
            NetworkRequest.Builder builder = new NetworkRequest.Builder();
            // 设置指定的网络传输类型(蜂窝传输) 等于手机网络
            builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
            // 设置感兴趣的网络功能
            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
            // 设置感兴趣的网络:计费网络
//            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);

            NetworkRequest request = builder.build();
            ConnectivityManager.NetworkCallback callback = new ConnectivityManager.NetworkCallback() {
                @TargetApi(Build.VERSION_CODES.M)
                @Override
                public void onAvailable(Network network) {
                    super.onAvailable(network);
                    Log.i("test", "已根据功能和传输类型找到合适的网络");
                    if (isNetwork) {
                        isNetwork = false;
                        connMgr.unregisterNetworkCallback(this);

                        // 可以通过下面代码将app接下来的请求都绑定到这个网络下请求
                        if (Build.VERSION.SDK_INT >= 23) {
                            connMgr.bindProcessToNetwork(network);
                        } else {// 23后这个方法舍弃了
                            ConnectivityManager.setProcessDefaultNetwork(network);
                        }
                        // 也可以在将来某个时间取消这个绑定网络的设置
                        // if (Build.VERSION.SDK_INT >= 23) {
                        //      onnectivityManager.bindProcessToNetwork(null);
                        //} else {
                        //     ConnectivityManager.setProcessDefaultNetwork(null);
                    }
                }
            };
            //connMgr.requestNetwork(request, callback);
            connMgr.registerNetworkCallback(request, callback);
        }
    }

    /*
    * WIFI是否连接
    * */
    private boolean isNetworkConnected() {
        NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
        return (networkInfo != null && networkInfo.isConnected());
    }

    /*
    * 外网是否可以访问
    * */
    public boolean isNetworkOnline() {
        Runtime runtime = Runtime.getRuntime();
        try {
            Process ipProcess = runtime.exec("ping -c 1 www.baidu.com");
            int exitValue = ipProcess.waitFor();
            return (exitValue == 0);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }

 

 

 

你可能感兴趣的:(Android)