一、前言
在应用开发过程中,总是需要获取网络状态,当前是否有网络,当前是使用数据网络还是使用无线网络。鸿蒙提供了一系列方法来获取网络状态。
二、添加权限
ohos.permission.GET_NETWORK_INFO 这个权限用于获取网络信息
ohos.permission.INTERNET 这个权限用于访问网络
这两个权限不需要动态申请,只需要在配置文件中声明即可。
添加权限的方式查看下图,如果你没办法像下图一样的操作,请把编译器升级到最新版。
添加权限.png
三、获取网络状态
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(NetHandle handle) | 网络连接成功回调 |
onLosing(NetHandle handle, long maxMsToLive) | 网络正在丢失连接 |
onLost(NetHandle handle) | 网络已断开连接 |
onBlockedStatusChanged(NetHandle handle, boolean blocked) | 访问的网络阻塞状态发生变化 |
onUnavailable() | 网络连接超时或网络不可达 |
onCapabilitiesChanged(NetHandle handle, NetCapabilities networkCapabilities) | 网络状态变化但仍旧是可用状态 |
onConnectionPropertiesChanged(NetHandle handle, ConnectionProperties connectionProperties) | 网络连接的属性被修改 |
其中最为常用的方法为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),其中常用参数如下:
参数 | 含义 |
---|---|
NetCapabilities.NET_CAPABILITY_INTERNET | 是否连接了网络,不关心是否可以上网,有时我们连接了一个网络,但由于网络已经到期(该交钱了)或者使用的代理不可用,设备虽然连接了网络,但是不能上网 |
NetCapabilities.NET_CAPABILITY_VALIDATED | 网络可用并且可以上网 |
hasBearer
可以判断网络的类型,同样有多个参数(具体的参数可查看NetCapabilities),其中常用参数如下:
参数 | 含义 |
---|---|
NetCapabilities.BEARER_WIFI | 表示接入的是WIFI网络 |
NetCapabilities.BEARER_WIFI_AWARE | 该网络支持WiFi |
NetCapabilities.BEARER_CELLULAR | 表示接入的是蜂窝网络 |
NetCapabilities.BEARER_ETHERNET | 表示接入的是以太网 |
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);
}
}
}
四、总结
本文主要是对获取当前网络状态以及监听网络状态进行讲解,需要注意当前的网络状态和实时的网络状态的区别。
最后奉上源码,代码运行起来后,大家可以随时打开或者关闭网络,以获取实时的网络状态。
网友评论