Android 使用ping判断网络/WIFI连接是否可用

最近项目中有一个网络判断的需求,因为终端只能连接wifi,wifi即使连接上也可能会出现不能连接网络的问题,所以需要进行网络连接的判断。
ping的相关知识

使用ping检验网络是否可以连接

ping就是检测客户端是否可以上网。
那么我们就上代码
该段代码来自http://blankj.com
导入常用工具包compile 'com.blankj:utilcode:1.9.8'
这个里边有各种各样的常用的工具类,下边的代码是NetworkUtils的一个方法;

/**
     * 判断网络是否可用
     * 

需添加权限 {@code }

*

需要异步ping,如果ping不通就说明网络不可用

* * @param ip ip地址(自己服务器ip),如果为空,ip为阿里巴巴公共ip * @return {@code true}: 可用
{@code false}: 不可用 */ public static boolean isAvailableByPing(String ip) { if (ip == null || ip.length() <= 0) { ip = "223.5.5.5";// 阿里巴巴公共ip } ShellUtils.CommandResult result = ShellUtils.execCmd(String.format("ping -c 1 %s", ip), false); boolean ret = result.result == 0; if (result.errorMsg != null) { Log.d("NetworkUtils", "isAvailableByPing() called" + result.errorMsg); } if (result.successMsg != null) { Log.d("NetworkUtils", "isAvailableByPing() called" + result.successMsg); } return ret; }

这段代码完全可以作为网络检测的使用,可是我在使用这段代码的时候偶尔会遇到anr的问题。出现anr就说明在主线程做了耗时操作,这是我没有将这段代码放到子线程造成的问题。其实ping也就相当于去请求网络,跟普通的接口请求差不多,当网络比较慢的时候就会消耗时间,放在主线程就会造成anr。
在修改bug的时候我对这段代码进行了一些修改:

   * 判断网络是否可用
     * 

需添加权限 {@code }

*

需要异步ping,如果ping不通就说明网络不可用

* * @param ip ip地址(自己服务器ip),如果为空,ip为阿里巴巴公共ip * @return {@code true}: 可用
{@code false}: 不可用 */ public static boolean isAvailableByPing(String ip) { if (ip == null || ip.length() <= 0) { ip = "223.5.5.5";// 阿里巴巴公共ip } Runtime runtime = Runtime.getRuntime(); Process ipProcess = null; try { //-c 后边跟随的是重复的次数,-w后边跟随的是超时的时间,单位是秒,不是毫秒,要不然也不会anr了 ipProcess = runtime.exec("ping -c 3 -w 3 "+ip); int exitValue = ipProcess.waitFor(); Log.i("Avalible", "Process:" + exitValue); return (exitValue == 0); } catch (IOException | InterruptedException e) { e.printStackTrace(); } finally { //在结束的时候应该对资源进行回收 if (ipProcess != null) { ipProcess.destroy(); } runtime.gc(); } return false; }

只需要把这个方法引用到子线程中就行了,其实不引用也可以,因为在这里设定了超时时间为3秒。但是最好是放到子线程里边。

问题补充

上边的代码在Android 7.1.2中出现了问题,好好的WIFI连接上之后,ping不通,每次waitfor都返回1,返回一表示WiFi连接,但是没有网络。其实是有网络的,很奇怪。
解决方法:
这里我获取了ping时抓包的信息,判断是否丢包为100%。如果为100%,就说明网络有问题。不是100%说明网络连接没问题。
废话不多说,直接上代码!老铁双击666,,哈哈

 public boolean isNetworkOnline() {

        Runtime runtime = Runtime.getRuntime();
        Process ipProcess = null;
        try {
            ipProcess = runtime.exec("ping -c 5 -w 4 223.5.5.5");
            InputStream input = ipProcess.getInputStream();

            BufferedReader in = new BufferedReader(new InputStreamReader(input));
            StringBuffer stringBuffer = new StringBuffer();
            String content = "";
            while ((content = in.readLine()) != null) {
                stringBuffer.append(content);
            }

            int exitValue = ipProcess.waitFor();
            if (exitValue == 0) {
                //WiFi连接,网络正常
                return true;
            } else {
                if (stringBuffer.indexOf("100% packet loss") != -1) {
                    //网络丢包严重,判断为网络未连接
                    return false;
                } else {
                    //网络未丢包,判断为网络连接
                    return true;
                }
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (ipProcess != null) {
                ipProcess.destroy();
            }
            runtime.gc();
        }
        return false;
    }

你可能感兴趣的:(Android 使用ping判断网络/WIFI连接是否可用)