ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

安卓(Android)网络管理工具,判断使用的网络类型、网络状态判断、以及可根据优先级自动切换到实际可以上外网的网络通道

2021-11-29 19:03:31  阅读:261  来源: 互联网

标签:return 安卓 网络 public boolean static NetworkCapabilities 上外 TRANSPORT


安卓(Android)网络管理工具

判断使用的网络类型、网络状态判断、以及可根据优先级自动切换到实际可以上外网的网络通道

本文连接:https://www.cnblogs.com/muphy/p/15620772.html

适用于以下需求:

1.物联网开发,为了满足网络可靠性,对安卓应用设置了多网口上网,WIFI或者以太网+4G网

2.当使用蜂窝网(4G)时限制数据上传频率,以太网或者WIFI网络不限制

3.需要确保连接上的以太网或者WIFI是否真的可以上外网,网络存在但不可以上网时绑定蜂窝网(4G)上网

 

 

NetWorkUtils.java

//package me.muphy.util;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.Build;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class NetWorkUtils {

    public static final String TAG = NetWorkUtils.class.getSimpleName();
    public static volatile boolean isActivityConnected = true;
    public static volatile boolean isConnected = true;
    private static ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public static List<NetworkCapabilities> getAllNetworkCapabilities() {
        ConnectivityManager connectivityManager = (ConnectivityManager) ContextHolder.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        Network[] networks = connectivityManager.getAllNetworks();
        List<NetworkCapabilities> list = new ArrayList<>();
        for (Network network : networks) {
            NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
            list.add(capabilities);
        }
        return list;
    }

    public static String getNetworkName(int transportType) {
        if (transportType == NetworkCapabilities.TRANSPORT_WIFI) {
            return "WIFI";
        } else if (transportType == NetworkCapabilities.TRANSPORT_CELLULAR) {
            return "蜂窝网络";
        } else if (transportType == NetworkCapabilities.TRANSPORT_ETHERNET) {
            return "以太网";
        } else {
            return "其他网络";
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public static int getTransportType(NetworkCapabilities networkCapabilities) {
        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
            return NetworkCapabilities.TRANSPORT_WIFI;
            //post(NetType.WIFI);
        } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
            return NetworkCapabilities.TRANSPORT_CELLULAR;
            //post(NetType.CMWAP);
        } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
            return NetworkCapabilities.TRANSPORT_ETHERNET;
            //post(NetType.AUTO);
        }
        return -1;
    }

    //以太网连上但不能上外网时,程序已经绑定了蜂窝网通道上网,此方法判断是否实际使用蜂窝网上网
    public static boolean isRealCellular() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            boolean activityCellular = isActivityCellular();
            if (activityCellular) {
                return true;
            }
            return !isActivityConnected;
        }
        return true;
    }

    //判断激活的网(默认网络)是否4G网
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static boolean isActivityCellular() {
        boolean isCellular = (getTransportType() == NetworkCapabilities.TRANSPORT_CELLULAR);
        return isCellular;
    }

    public static boolean isCellular(int transportType) {
        boolean isCellular = (transportType == NetworkCapabilities.TRANSPORT_CELLULAR);
        return isCellular;
    }

    //判断激活的网(默认网络)是否4G网
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static boolean isActivityWifi() {
        boolean isWifi = (getTransportType() == NetworkCapabilities.TRANSPORT_WIFI);
        return isWifi;
    }

    public static boolean isWifi(int transportType) {
        boolean isWifi = (transportType == NetworkCapabilities.TRANSPORT_WIFI);
        return isWifi;
    }

    //判断激活的网(默认网络)是否4G网
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static boolean isActivityEthernet() {
        boolean isEthernet = (getTransportType() == NetworkCapabilities.TRANSPORT_ETHERNET);
        return isEthernet;
    }

    public static boolean isEthernet(int transportType) {
        boolean isEthernet = (transportType == NetworkCapabilities.TRANSPORT_ETHERNET);
        return isEthernet;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public static int getTransportType() {
        int transportType = -2;
        ConnectivityManager connectivityManager = (ConnectivityManager) ContextHolder.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        Network activeNetwork = connectivityManager.getActiveNetwork();
        if (activeNetwork == null) {
            isConnected = false;
        } else {
            NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork);
            if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
                isConnected = true;
                transportType = getTransportType(networkCapabilities);
            } else {
                isConnected = false;
            }
        }
        return transportType;
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public static void requestNetwork() {
        final ConnectivityManager connectivityManager = (ConnectivityManager) ContextHolder.getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkRequest.Builder builder = new NetworkRequest.Builder();
        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        NetworkRequest networkRequest = builder.build();
        ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback() {
            @Override
            public void onAvailable(Network network) {
                if (Build.VERSION.SDK_INT >= 23) {
                    connectivityManager.bindProcessToNetwork(network);
                } else {
                    // 23后这个方法舍弃了
                    ConnectivityManager.setProcessDefaultNetwork(network);
                }
            }
        };
        final boolean[] chanelFlag = {true};
        executorService.scheduleWithFixedDelay(() -> {
            try {
                //网络都没连接直接返回
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    if (isActivityCellular()) {
                        return;
                    }
                }
                if (!isConnected) {
                    return;
                }
                isActivityConnected = ping();
                if (isActivityConnected) {
                    if (chanelFlag[0]) {
                        return;
                    }
                    chanelFlag[0] = true;
                    //1.以太网络可上外网时改为默认优先级上网
                    if (Build.VERSION.SDK_INT >= 23) {
                        connectivityManager.bindProcessToNetwork(null);
                    } else {
                        ConnectivityManager.setProcessDefaultNetwork(null);
                    }
                    connectivityManager.unregisterNetworkCallback(networkCallback);
                } else if (chanelFlag[0]) {
                    //2.以太网络不可上外网时自动切换蜂窝网
                    connectivityManager.requestNetwork(networkRequest, networkCallback);
                    chanelFlag[0] = false;
                }
            } catch (Exception e) {
                e.printStackTrace();
                LogFileUtils.exceptionToFile(e);
            }
        }, 1, 5, TimeUnit.SECONDS);
    }

    // PING命令 使用新进程使用默认网络 不会使用 networkCallback 绑定的通道  用来判断以太网或者WiFi是否可上外网非常不错
    public static boolean ping() {
        Runtime runtime = Runtime.getRuntime();
        try {
            Process p = runtime.exec("ping -c 1 -W 1 www.baidu.com");
            int ret = p.waitFor();
            Log.i(TAG, "Process:" + ret);
            return ret == 0;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

 

标签:return,安卓,网络,public,boolean,static,NetworkCapabilities,上外,TRANSPORT
来源: https://www.cnblogs.com/muphy/p/15620772.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有