当targetSdkVersion <29 之前判断设备当前是否连接网络的时候,直接用的getActiveNetworkInfo是这样的方式:
// 当前网络是否可用
public boolean isInternetAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
但是当targetSdkVersion=29的时候,ConnectivityManager.getActiveNetworkInfo()方法被标为deprecated了。根据Google官方文档中提供了几个新API来获取当前的网络状态。
1.异步获取
使用ConnectivityManager.NetworkCallback回调。
2.同步获取
使用ConnectivityManager.getNetworkCapabilities(network: Network?)和ConnectivityManager.getLinkProperties(network: Network?)方法。
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
}
@Override
public void onLosing(Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
}
@Override
public void onLost(Network network) {
super.onLost(network);
}
@Override
public void onUnavailable() {
super.onUnavailable();
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities);
}
@Override
public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {
super.onLinkPropertiesChanged(network, linkProperties);
}
@Override
public void onBlockedStatusChanged(Network network, boolean blocked) {
super.onBlockedStatusChanged(network, blocked);
}
});
}
tip:
建议只监测onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities)回调,因为别的回调在连接上VPN后,在APP使用过程中就完全不会被调用。
会调用,可能常用的API就以下几个:
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_XXX)
括号中的参数主要用到的就是NetworkCapabilities.NET_CAPABILITY_INTERNET和NetworkCapabilities.NET_CAPABILITY_VALIDATED
NET_CAPABILITY_INTERNET:表示是否连接到互联网,即是否连接上了WIFI或者移动蜂窝网络,这个为TRUE不一定能正常上网
NET_CAPABILITY_VALIDATED:表示是否确实能和连接的互联网通信,这个为TRUE,才是真的能上网
tip:
其余还有十几个参数,各自的意思,直接看文档或者源码即可。
这些参数表示的状态是可以共存的,也就是说networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)和networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)的返回值可能同时为TRUE。
networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_XXX)
括号中的参数主要用到的就是NetworkCapabilities.TRANSPORT_CELLULAR和NetworkCapabilities.TRANSPORT_WIFI
TRANSPORT_CELLULAR:表示当前接入的是否是蜂窝网络
TRANSPORT_WIFI:表明当前接入的是WIFI网络,还有一些别的蓝牙网络,有线网络等等可以直接查看文档或源码了解
tip:
这些参数表示的状态是不可共存的,即你不可能又连接到蜂窝网络又连接到WIFI网络,它们同时只会有一个返回TRUE。
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
if(networkCapabilities!=null && networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)){
return true;
}
}
对目前使用的获取当前是否联网的工具方法改造一下。虽然Google是建议使用回调,但我还是用同步方法吧,这样就不用又是回调又是同步获取那么麻烦了,顺手一点。
/**
* 检测网络连接状态是否可用
*
* @return
*/
public boolean isNetAvailable(Context context) {
if (context!= null) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm != null) {
if (Build.VERSION.SDK_INT < 23) {
NetworkInfo mWiFiNetworkInfo = cm.getActiveNetworkInfo();
if (mWiFiNetworkInfo != null) {
if (mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI) {//WIFI
return true;
} else if (mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {//移动数据
return true;
}
}
} else {
Network network = cm.getActiveNetwork();
if (network != null) {
NetworkCapabilities nc = cm.getNetworkCapabilities(network);
if (nc != null) {
if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {//WIFI
return true;
} else if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {//移动数据
return true;
}
}
}
}
}
}
return false;
}