一、前言
在应用开发过程中,总是需要获取网络状态,当前是否有网络,当前是使用数据网络还是使用无线网络。鸿蒙提供了一系列方法来获取网络状态。
二、添加权限
ohos.permission.GET_NETWORK_INFO 这个权限用于获取网络信息。
ohos.permission.INTERNET 这个权限用于访问网络1.2。
这两个权限不需要动态申请,只需要在配置文件中声明即可。
添加权限的方式查看下图,如果你没办法像下图一样的操作,请把编译器升级到最新版。
三、获取网络状态
3、1 获取当前的网络状态
下面的类可以获取当前的网络状态,并且可以判断能否上网。有时我们连接了一个网络,但由于网络已经到期(该交钱了)或者代理不可用,设备虽然连接了网络,但是不能上网。
- public class NetworkUtil {
- /**
- * 网络是否连接
- *
- * @param context 上下文
- * @return true表示网络已经连接,并且可以上网。false表示网络没连接,或者网络连接了,但是不能上网
- */
- public static boolean isNetworkConnectedInternet(Context context) {
- NetManager netManager = NetManager.getInstance(context);
- NetCapabilities netCapabilities = netManager.getNetCapabilities(netManager.getDefaultNet());
- // NetCapabilities.NET_CAPABILITY_VALIDATED表示连接了网络,并且可以上网
- return netCapabilities.hasCap(NetCapabilities.NET_CAPABILITY_VALIDATED);
- }
- /**
- * 是否是WiFi连接
- *
- * @param context 上下文
- * @return true表示WiFi连接,并且可以上网。false表示WiFi没连接,或者WiFi连接了,但是不能上网
- */
- public static boolean isWifiConnectedInternet(Context context) {
- // 获取网络管理对象
- NetManager netManager = NetManager.getInstance(context);
- // 获取NetCapabilities对象
- NetCapabilities netCapabilities = netManager.getNetCapabilities(netManager.getDefaultNet());
- // NetCapabilities.NET_CAPABILITY_VALIDATED表示连接了网络,并且可以上网
- return netCapabilities.hasCap(NetCapabilities.NET_CAPABILITY_VALIDATED) &&
- netCapabilities.hasBearer(NetCapabilities.BEARER_WIFI) ||
- netCapabilities.hasBearer(NetCapabilities.BEARER_WIFI_AWARE);
- }
- /**
- * 是否是数据网络连接
- *
- * @param context 上下文
- * @return true表示数据网络连接,并且可以上网。false表示数据网络没连接,或者数据网络连接了,但是不能上网
- */
- public static boolean isMobileConnectedInternet(Context context) {
- NetManager netManager = NetManager.getInstance(context);
- NetCapabilities netCapabilities = netManager.getNetCapabilities(netManager.getDefaultNet());
- // NetCapabilities.NET_CAPABILITY_VALIDATED表示连接了网络,并且可以上网
- return netCapabilities.hasCap(NetCapabilities.NET_CAPABILITY_VALIDATED) &&
- netCapabilities.hasBearer(NetCapabilities.BEARER_CELLULAR);
- }
- /**
- * 这种方式也可以判断网络是否连接
- *
- * @param context 上下文
- * @return 只要网络已经连接,就返回true,不管能不能上网。有时我们连接了一个网络,但由于网络已经到期(该交钱了)或者使用的代理不可用,设备虽然连接了网络,但是不能上网
- */
- public static boolean isNetworkConnected(Context context) {
- NetManager netManager = NetManager.getInstance(context);
- NetHandle[] allNets = netManager.getAllNets();
- return allNets != null && allNets.length > 0;
- }
- /**
- * 是否是WiFi连接
- *
- * @param context 上下文
- * @return 只要是WiFi连接,就返回true,不管能不能上网。有时我们连接了一个网络,但由于网络已经到期(该交钱了)或者使用的代理不可用,设备虽然连接了网络,但是不能上网
- */
- public static boolean isWifiConnected(Context context) {
- // 获取网络管理对象
- NetManager netManager = NetManager.getInstance(context);
- // 获取NetCapabilities对象
- NetCapabilities netCapabilities = netManager.getNetCapabilities(netManager.getDefaultNet());
- return netCapabilities.hasBearer(NetCapabilities.BEARER_WIFI) ||
- netCapabilities.hasBearer(NetCapabilities.BEARER_WIFI_AWARE);
- }
- /**
- * 是否是数据网络连接
- *
- * @param context 上下文
- * @return 只要是数据网络连接,就返回true,不管能不能上网。有时我们连接了一个网络,但由于网络已经到期(该交钱了),设备虽然连接了网络,但是不能上网
- */
- public static boolean isMobileConnected(Context context) {
- NetManager netManager = NetManager.getInstance(context);
- NetCapabilities netCapabilities = netManager.getNetCapabilities(netManager.getDefaultNet());
- return netCapabilities.hasBearer(NetCapabilities.BEARER_CELLULAR);
- }
- }
3、2 获取实时的网络状态,监听网络状态
上面的方式只能获取到当前的网络状态,并不能获取到实时的网络状态。用户可以随时打开或者关闭网络,当用户打开或者关闭网络的时候,我们希望可以实时的获取到网络状态。要想获取到实时的网络状态,就需要对网络进行监听。
NetStatusCallback用于监听网络的状态,可以继承该类来监听网络的状态。它有以下几个方法:
其中最为常用的方法为onAvailable,onLost,onCapabilitiesChanged方法。
自定义一个类,继承NetStatusCallback。
- /**
- * @author 裴云飞
- * @date 2021/4/11
- */
- public class DefaultNetStatusCallback extends NetStatusCallback {
- @Override
- public void onAvailable(NetHandle handle) {
- super.onAvailable(handle);
- LogUtils.d("yunfei", "网络连接成功");
- }
- @Override
- public void onBlockedStatusChanged(NetHandle handle, boolean blocked) {
- super.onBlockedStatusChanged(handle, blocked);
- LogUtils.d("yunfei", "访问的网络阻塞状态发生变化");
- }
- @Override
- public void onLosing(NetHandle handle, long maxMsToLive) {
- super.onLosing(handle, maxMsToLive);
- LogUtils.d("yunfei", "网络正在丢失连接");
- }
- @Override
- public void onLost(NetHandle handle) {
- super.onLost(handle);
- LogUtils.d("yunfei", "网络已断开连接");
- }
- @Override
- public void onUnavailable() {
- super.onUnavailable();
- LogUtils.d("yunfei", "网络连接超时或网络不可达");
- }
- @Override
- public void onCapabilitiesChanged(NetHandle handle, NetCapabilities networkCapabilities) {
- super.onCapabilitiesChanged(handle, networkCapabilities);
- LogUtils.d("yunfei", "网络状态变化但仍旧是可用状态");
- }
- @Override
- public void onConnectionPropertiesChanged(NetHandle handle, ConnectionProperties connectionProperties) {
- super.onConnectionPropertiesChanged(handle, connectionProperties);
- LogUtils.d("yunfei", "网络连接的属性被修改");
- }
- }
onCapabilitiesChanged(NetHandle handle, NetCapabilities networkCapabilities)是较为常用的网络状态发生变化时的监听,其中的参数networkCapabilities有两个常用的方法。
hasCap判断网络是否连接,有多个参数(具体的参数可查看NetCapabilities),其中常用参数如下:
hasBearer可以判断网络的类型,同样有多个参数(具体的参数可查看NetCapabilities),其中常用参数如下:
onCapabilitiesChanged(NetHandle handle, NetCapabilities networkCapabilities)的具体使用如下:
- @Override
- public void onCapabilitiesChanged(NetHandle handle, NetCapabilities networkCapabilities) {
- super.onCapabilitiesChanged(handle, networkCapabilities);
- LogUtils.d("yunfei", "网络状态变化但仍旧是可用状态");
- if (networkCapabilities.hasCap(NetCapabilities.NET_CAPABILITY_VALIDATED)) {
- // 网络连接成功,并且可以上网
- if (networkCapabilities.hasBearer(NetCapabilities.BEARER_WIFI)||
- networkCapabilities.hasBearer(NetCapabilities.BEARER_WIFI_AWARE)) {
- LogUtils.d("yunfei", "使用WiFi");
- } else if (networkCapabilities.hasBearer(NetCapabilities.BEARER_CELLULAR) ||
- networkCapabilities.hasBearer(NetCapabilities.BEARER_ETHERNET)) {
- LogUtils.d("yunfei", "使用数据网络");
- } else {
- // 其它网络,包括蓝牙、VPN、LoWPAN等
- LogUtils.d("yunfei", "其它网络");
- }
- }
- }
定义好监听网络的类后,就可以使用了。要想获取当前的网络状态,直接调用NetworkUtil类中的方法即可。要想获取实时的网络状态,就需要添加监听,首先获取网络管理对象,然后添加监听,这样就能实时的监听到网络的状态了。最后别忘了在onStop方法里面移除监听。
- public class MainAbilitySlice extends AbilitySlice {
- private NetManager netManager;
- private DefaultNetStatusCallback mDefaultNetStatusCallback = new DefaultNetStatusCallback();
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main);
- /*
- * 网络是否连接,true表示网络已经连接,但未必可以上网,
- * 有时我们连接了一个网络,但由于网络已经到期(该交钱了)或者使用的代理不可用,
- * 设备虽然连接了网络,但是不能上网
- */
- boolean networkConnect = NetworkUtil.isNetworkConnected(this);
- // 是否是WiFi连接,只要是WiFi连接,就返回true,不管能不能上网。
- boolean wifiConnected = NetworkUtil.isWifiConnected(this);
- // 否是数据网络连接,只要是数据网络连接,就返回true,不管能不能上网
- boolean mobileConnected = NetworkUtil.isMobileConnected(this);
- // 网络是否连接,true表示网络已经连接,并且可以上网
- boolean networkConnectedInternet = NetworkUtil.isNetworkConnectedInternet(this);
- // 是否是WiFi连接,true表示WiFi连接,并且可以上网
- boolean wifiConnectedInternet = NetworkUtil.isWifiConnectedInternet(this);
- // 是否是数据网络连接,true表示数据网络连接,并且可以上网
- boolean mobileConnectedInternet = NetworkUtil.isMobileConnectedInternet(this);
- /*
- * 下面的代码用于获取实时的网络状态。用户可以随时打开或者关闭网络,当用户打开或者关闭网络时,
- * 我们可以获取实时的网络状态
- */
- // 获取网络管理对象
- netManager = NetManager.getInstance(this);
- // 添加监听,监听实时的网络状态
- netManager.addDefaultNetStatusCallback(mDefaultNetStatusCallback);
- }
- @Override
- public void onActive() {
- super.onActive();
- }
- @Override
- public void onForeground(Intent intent) {
- super.onForeground(intent);
- }
- @Override
- protected void onStop() {
- super.onStop();
- if (netManager != null) {
- // 移除监听
- netManager.removeNetStatusCallback(mDefaultNetStatusCallback);
- }
- }
- }
四、总结
本文主要是对获取当前网络状态以及监听网络状态进行讲解,需要注意当前的网络状态和实时的网络状态的区别。
最后奉上源码,代码运行起来后,大家可以随时打开或者关闭网络,以获取实时的网络状态。