Android实时监测网络连接状态及网络是否可用,类似微信的功能。

Posted 陳英傑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android实时监测网络连接状态及网络是否可用,类似微信的功能。相关的知识,希望对你有一定的参考价值。

实现实时监控网络变化,类似于微信的功能,当网络不可用时app能实时感知到,网上找了很多例子并不能实现,或者只实现其中一部分功能,我就参考大家的方法做一个组合。

一、网络状态变化监测,此方式只能监测网络连接改变,不能判断是否可用(例如网络连接正常,但是不能访问网络)。
在使用时定义一个方法,名字随便,参数必须是一个NetWorkState类型:

// 监听网络变化类型
    @NetWorkMonitor(monitorFilter = NetWorkState.WIFI, NetWorkState.GPRS, NetWorkState.NONE)
    public void onNetworkStateChange(NetWorkState workState) 
        // workState包含三种类型
    

二、判断网络连接是否可用
经过测试NetworkInfo.isAvailable()此方式也不能判断连接的网络是否可用。
比较靠谱的是通过ping一个公网地址的方式:
ping命令有几个参数,可百度查阅。

public boolean isAvailable() 
	Runtime runtime = Runtime.getRuntime();
    try 
        // 会阻塞线程 ping baidu 1次
        Process exec = runtime.exec("ping -c 1 www.baidu.com");
        int i = exec.waitFor();
        //wifi不可用或未连接,返回2;WiFi需要认证,返回1;WiFi可用,返回0;
        return i == 0;
     catch (Exception e) 
        e.printStackTrace();
    
    return false;

但是此方法会阻塞线程,不能在主线程执行,自然想到通过子线程执行,但是在测试中我发现,假如从wifi1切换到wifi2(移动网络开启的),执行顺序是:NONE->GPRS->WIFI,有多个状态,如果在这些个状态变化时执行上面方法,并不一定是按顺序返回结果,所以我才用任务队列的方式去执行。

在使用时:

public class MainActivity extends AppCompatActivity 

    private String[] permissions = 
            Manifest.permission.READ_PHONE_STATE
    ;
    private NetQueue netQueue;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 
            requestPermissions(permissions, 1);
        

        // 创建单任务队列,任务按顺序依次执行。
        netQueue = new NetQueue(1);
        netQueue.start();
    

    // 监听网络变化类型
    @NetWorkMonitor(monitorFilter = NetWorkState.WIFI, NetWorkState.GPRS, NetWorkState.NONE)
    public void onNetworkStateChange(NetWorkState workState) 
        NetCheckTask task = new NetCheckTask(this, isAvailable -> 
            Log.e("MainActivity", "onResult:" + (isAvailable ? "网络可用" : "网络不可用") + ", Thread:" + Thread.currentThread().toString());
        
        );
        netQueue.add(task);
    

    @Override
    protected void onStart() 
        super.onStart();
        NetManager.getInstance().register(this);
    

    @Override
    protected void onDestroy() 
        super.onDestroy();
        NetManager.getInstance().unregister(this);
    

NetCheckTask类:

public class NetCheckTask implements ITask 

    private Context context;
    private NetCheckCallback callback;

    public NetCheckTask(Context context, NetCheckCallback callback) 
        this.context = context;
        this.callback = callback;
    

    @Override
    public void checkNet() 
        // do something
        Runtime runtime = Runtime.getRuntime();
        try 
            // 会阻塞线程 ping baidu 1次
            Process exec = runtime.exec("ping -c 1 www.baidu.com");
            int i = exec.waitFor();
            //wifi不可用或未连接,返回2;WiFi需要认证,返回1;WiFi可用,返回0;
            if (context != null && callback != null) 
                new Handler(context.getMainLooper()).post(() -> callback.onResult(i == 0));
            
         catch (Exception e) 
            e.printStackTrace();
            // 异常处理
        
    

此方法只能在网络切换时才会判断网络是否可用,微信可以在不切换网络时监测是否可用,我猜这是基于他们的IM系统做的,如果我们也想达到这种效果也是可以的,例如轮询调用ping方法等。完整代码在我的资源中下载。

以上是关于Android实时监测网络连接状态及网络是否可用,类似微信的功能。的主要内容,如果未能解决你的问题,请参考以下文章

网站安全DDOS攻击及监测

关于网络状态监听实时,创建单例网络监测(非实时)

Android网络状态判断与处理

通过RealReachability实现当前网络的监测

Android检测网络状态,判断当前网络是否可用

使用Reachability实时监测网络连通性