前言
如今在Android 7.0版本以上判断网络是否可用,一般采用会ConnectivityManager.NetworkCallback,对其回调内NetworkCapabilities
包含的Transports
或Capabilities
进行判断的方案,Android官方文档。经测试,有3中方案可行。
例如以下是一次状态回调包含的内容:
Transports
: WIFI|VPN // 这个尤为重要
Capabilities
:
NOT_METERED
&INTERNET
&NOT_RESTRICTED
&TRUSTED
&VALIDATED
&NOT_ROAMING
&FOREGROUND
&NOT_CONGESTED
&NOT_SUSPENDED
LinkUpBandwidth
>=176231Kbps LinkDnBandwidth
>=176231Kbps
AdministratorUids
: []
RequestorUid
: -1
RequestorPackageName
: null
使用方法
// 在onResume调用
private void registerNetworkStatus() {
Context context = getContext();
if (context != null) {
ConnectivityManager networkService = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
networkService.registerDefaultNetworkCallback(networkCallback);
} else {
networkService.registerNetworkCallback(new NetworkRequest.Builder().build(), networkCallback);
}
}
}
// 在onPause调用
private void unRegisterNetworkStatus() {
Context context = getContext();
if (context != null) {
ConnectivityManager networkService = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
networkService.unregisterNetworkCallback(networkCallback);
}
}
// 监听回调
private final ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback(){
@Override
public void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities);
Log.d(TAG, "onCapabilitiesChanged: 网络状态改变--->" + networkCapabilities.toString());
if (NetworkUtils.isEnableToNetwork(getContext(), networkCapabilities)) {
Log.d(TAG, "onCapabilitiesChanged ---> 网络可用");
}
}
};
/**
* 检测网络连接状态是否可用,这里采用的第一种方案
* 以下是可用网络:
* NetworkCapabilities.TRANSPORT_CELLULAR,
* NetworkCapabilities.TRANSPORT_WIFI,
* NetworkCapabilities.TRANSPORT_BLUETOOTH,
* NetworkCapabilities.TRANSPORT_ETHERNET,
* NetworkCapabilities.TRANSPORT_VPN,
* NetworkCapabilities.TRANSPORT_WIFI_AWARE,
* NetworkCapabilities.TRANSPORT_LOWPAN
*/
@SuppressLint("WrongConstant")
public static boolean isEnableToNetwork(Context context, NetworkCapabilities networkCapabilities) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
if (context == null) return false;
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null) return false;
NetworkInfo mWiFiNetworkInfo = cm.getActiveNetworkInfo();
return mWiFiNetworkInfo != null &&
(mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI || mWiFiNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
} else {
return networkCapabilities != null &&
networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
方案一、使用Capabilities
NetworkCapabilities.hasCapability()
方案二、使用Transports
NetworkCapabilities.hasTransport()
以下都是可用的网络,根据实际需求使用(基本上所有情况都符合实际需求):
NetworkCapabilities.TRANSPORT_CELLULAR
NetworkCapabilities.TRANSPORT_WIFI
NetworkCapabilities.TRANSPORT_BLUETOOTH
NetworkCapabilities.TRANSPORT_ETHERNET
NetworkCapabilities.TRANSPORT_VPN
NetworkCapabilities.TRANSPORT_WIFI_AWARE
NetworkCapabilities.TRANSPORT_LOWPAN
方案三、使用LinkUpBandwidth
和LinkDnBandwidth
判断上下行的网络速率,如果不可用的话不会超过100kbps
另外提醒:hasCapability 和 hasTransport 不要用错了