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方法等。完整代码在我的资源中下载。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值