使用compileSdkVersion 23,但尝试支持至少到9。
getNetworkInfo(int)
在23中已被弃用。建议使用getAllNetworks()
和getNetworkInfo(Network)
代替。但是这两个都需要最低API 21。
有没有一个可以在支持包中使用的类来帮助解决这个问题?
我知道有一个解决方案before,但是我的最低API要求为9,这是一个问题。
使用compileSdkVersion 23,但尝试支持至少到9。
getNetworkInfo(int)
在23中已被弃用。建议使用getAllNetworks()
和getNetworkInfo(Network)
代替。但是这两个都需要最低API 21。
有没有一个可以在支持包中使用的类来帮助解决这个问题?
我知道有一个解决方案before,但是我的最低API要求为9,这是一个问题。
由于发布的答案只允许查询活动网络,以下是如何获取任何网络的NetworkInfo
,而不仅仅是活动网络(例如Wifi网络)(抱歉,下面是Kotlin代码)
(getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).run {
allNetworks.find { getNetworkInfo(it).type == ConnectivityManager.TYPE_WIFI }?.let { network -> getNetworkInfo(network) }
// getNetworkInfo(ConnectivityManager.TYPE_WIFI).isAvailable // This is the deprecated API pre-21
}
android.permission.ACCESS_NETWORK_STATE
。cm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
。 - tmm1截至Android M (API 23),某些属性(例如getActiveNetworkInfo()
)已弃用。
将此处的答案和最新的指导以及API结合起来,使用Kotlin编写一个非常有用的扩展函数。您可以在一个单独的文件中编写以下内容:
fun Context.hasNetwork(): Boolean {
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkConnected(connectivityManager)
} else {
checkConnectedLegacy(connectivityManager)
}
}
@RequiresApi(Build.VERSION_CODES.M)
fun checkConnected(connectivityManager: ConnectivityManager): Boolean {
val activeNetwork = connectivityManager.activeNetwork
activeNetwork ?: return false
val capabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
capabilities ?: return false
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
}
fun checkConnectedLegacy(connectivityManager: ConnectivityManager): Boolean {
val networkInfo = connectivityManager.activeNetworkInfo
networkInfo ?: return false
return networkInfo.isConnected && (networkInfo.type == ConnectivityManager.TYPE_WIFI || networkInfo.type == ConnectivityManager.TYPE_MOBILE)
}
这将允许您从任何可以访问上下文的地方编写以下内容,例如对于片段:
if (requireContext().hasNetwork()) {
// do whatever if you HAVE network
} else {
// handle no network state
}
public boolean hasConnection(final Context context){
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNW = cm.getActiveNetworkInfo();
if (activeNW != null && activeNW.isConnected())
{
return true;
}
return false;
}
在主程序体中:
if(hasConnection(this)) {
Toast.makeText(this, "Active networks OK ", Toast.LENGTH_LONG).show();
getAccountData(token, tel);
}
else Toast.makeText(this, "No active networks... ", Toast.LENGTH_LONG).show();
NetManager 是一个可以用Kotlin编写的工具,用于检查Android上的互联网连接。
如果您使用的minSdkVersion >= 23
class NetManager @Inject constructor(var applicationContext: Context) {
val isConnectedToInternet: Boolean?
get() = with(
applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
) {
isConnectedToInternet()
}
}
fun ConnectivityManager.isConnectedToInternet() = isConnected(getNetworkCapabilities(activeNetwork))
fun isConnected(networkCapabilities: NetworkCapabilities?): Boolean {
return when (networkCapabilities) {
null -> false
else -> with(networkCapabilities) { hasTransport(TRANSPORT_CELLULAR) || hasTransport(TRANSPORT_WIFI) }
}
}
class NetManager @Inject constructor(var applicationContext: Context) {
val isConnectedToInternet: Boolean?
get() = with(
applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE)
as ConnectivityManager
) {
isConnectedToInternet()
}
}
fun ConnectivityManager.isConnectedToInternet(): Boolean = if (Build.VERSION.SDK_INT < 23) {
isConnected(activeNetworkInfo)
} else {
isConnected(getNetworkCapabilities(activeNetwork))
}
fun isConnected(network: NetworkInfo?): Boolean {
return when (network) {
null -> false
else -> with(network) { isConnected && (type == TYPE_WIFI || type == TYPE_MOBILE) }
}
}
fun isConnected(networkCapabilities: NetworkCapabilities?): Boolean {
return when (networkCapabilities) {
null -> false
else -> with(networkCapabilities) { hasTransport(TRANSPORT_CELLULAR) || hasTransport(TRANSPORT_WIFI) }
}
}
public boolean isConnectedToWifi(Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) {
return false;
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Network network = connectivityManager.getActiveNetwork();
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities == null) {
return false;
}
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
} else {
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (networkInfo == null) {
return false;
}
return networkInfo.isConnected();
}
}
使用 目标 SDK 29 检查网络状态:
@IntRange(from = 0, to = 3)
fun getConnectionType(context: Context): Int {
var result = 0 // Returns connection type. 0: none; 1: mobile data; 2: wifi
val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val capabilities =
cm.getNetworkCapabilities(cm.activeNetwork)
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
result = 2
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
result = 1
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
result = 3
}
}
} else {
val activeNetwork = cm.activeNetworkInfo
if (activeNetwork != null) {
// connected to the internet
if (activeNetwork.type === ConnectivityManager.TYPE_WIFI) {
result = 2
} else if (activeNetwork.type === ConnectivityManager.TYPE_MOBILE) {
result = 1
} else if (activeNetwork.type === ConnectivityManager.TYPE_VPN) {
result = 3
}
}
}
return result
}
这对我在 Kotlin 中有效。许多 API 在 Network Manager 类中已被弃用,所以下面的答案涵盖了所有 API 支持。
fun isNetworkAvailable(context: Context): Boolean {
var result = false
(context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
result = isCapableNetwork(this,this.activeNetwork)
} else {
val networkInfos = this.allNetworks
for (tempNetworkInfo in networkInfos) {
if(isCapableNetwork(this,tempNetworkInfo))
result = true
}
}
}
return result
}
fun isCapableNetwork(cm: ConnectivityManager,network: Network?): Boolean{
cm.getNetworkCapabilities(network)?.also {
if (it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return true
} else if (it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return true
}
}
return false
}
您还需要添加以下内容
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
class Util {
public static boolean hasNetwork(@NonNull Context context) {
try {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return checkConnected(connectivityManager);
} else {
return checkConnectedLegacy(connectivityManager);
}
} catch (Exception e) {
Logger.e(e);
}
return false;
}
@RequiresApi(Build.VERSION_CODES.M)
public static boolean checkConnected(ConnectivityManager connectivityManager) {
Network network = connectivityManager.getActiveNetwork();
if (network == null) return false;
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities == null) return false;
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
}
public static boolean checkConnectedLegacy(ConnectivityManager connectivityManager) {
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnectedOrConnecting() && (networkInfo.getType() == ConnectivityManager.TYPE_WIFI || networkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
}
}
使用方法:
if(Util.hasNetwork(context){
//your code...
}