在API 29中,getActiveNetworkInfo()已被弃用。

43

我正在使用一个代码来检查用户是否有互联网连接,但是在针对sdk29时,下面的函数已经被弃用:

NetworkInfo

NetworkInfo.isConnected()

getActiveNetworkInfo()

这是代码:

public static boolean isNetworkAvailable(Context context) {
    if(context == null) { return false; }
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    // if no network is available networkInfo will be null, otherwise check if we are connected
    try {
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
            Log.i("update_statut","Network is available : true");
            return true;
        }
    } catch (Exception e) {
        Log.i("update_statut",""+ e.getMessage());
    }
    Log.i("update_statut","Network is available : FALSE ");
    return false;
}

https://dev59.com/JVQJ5IYBdhLWcg3wlm_B#53532456 - AskNilesh
3个回答

88

基于Google文档,它已被弃用。

  • getActiveNetworkInfo在API 29上已被弃用。
  • getAllNetworkInfo在API 23上已被弃用。

因此,如果您想查找网络连接状态,您可以使用此代码。

kotlin:

private fun isNetworkAvailable(context: Context): Boolean {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val nw      = connectivityManager.activeNetwork ?: return false
        val actNw = connectivityManager.getNetworkCapabilities(nw) ?: return false
        return when {
            actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
            actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
            //for other device how are able to connect with Ethernet
            actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
            //for check internet over Bluetooth
            actNw.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH) -> true
            else -> false
        }
    } else {
        val nwInfo = connectivityManager.activeNetworkInfo ?: return false
        return nwInfo.isConnected
    }
}

Java :

Java :
private Boolean isNetworkAvailable(Application application) {
    ConnectivityManager connectivityManager = (ConnectivityManager) application.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        Network nw = connectivityManager.getActiveNetwork();
        if (nw == null) return false;
        NetworkCapabilities actNw = connectivityManager.getNetworkCapabilities(nw);
        return actNw != null && (actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) || actNw.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH));
    } else {
        NetworkInfo nwInfo = connectivityManager.getActiveNetworkInfo();
        return nwInfo != null && nwInfo.isConnected();
    }
}

在这里你可以查看所有NetworkCapability


1
检查不应该针对Build.VERSION_CODES.Q(API 29)吗? - Cheok Yan Cheng
如果设备正在使用 VPN,您还需要检查 NetworkCapabilities.TRANSPORT_VPN - Ondřej Z
嗨,请检查您的代码:getter for activeNetworkInfo: NetworkInfo?'已被弃用。在Java中已被弃用。 - Mori
@Mori 是的,它已经被弃用了,但是在 Android 23 以下我们没有 activeNetwork,所以除非你的 Android 版本 >= 23,否则我们仍然需要使用它。 - Yoshimitsu
在漫游时使用NetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)。 - Osagui Aghedo
显示剩余6条评论

42

我终于找到了一段适用于所有API的代码,如果有人需要的话。

在API 29中,NetworkCapabilities并没有被弃用,但它只支持API 21及以上版本,因此我仅在API 29上调用它。

然而,在API 29中仅有getActiveNetworkInfo()被弃用,而它在所有API上都可用,因此我们可以在API 29以下的所有API中使用它。

这是代码:

    public static boolean isNetworkAvailable(Context context) {
    if(context == null)  return false;


    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connectivityManager != null) {


    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    return true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    return true;
                }  else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)){
                    return true;
                }
            }
        }

    else {

        try {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
                Log.i("update_statut", "Network is available : true");
                return true;
            }
        } catch (Exception e) {
            Log.i("update_statut", "" + e.getMessage());
        }
    }
}
    Log.i("update_statut","Network is available : FALSE ");
    return false;
}

这段代码有一些问题。一旦Android R发布,这段代码就会崩溃...这太可怕了。它还假设用户只能通过蜂窝数据或WiFi连接到互联网。那么以太网呢?我也用过。这段代码会让我的应用程序崩溃。 - Zun
@Zun 为什么它会在Android R上中断?注:请检查我对以太网电缆的编辑 - Chaouki Anass
android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.Q 这意味着新函数只会在 Android Q 中被调用。而不是在 Android Q 或更高版本中。因为 if 语句将进入 else,所以 Android R 将调用旧的、过时的函数! - Zun
@Zun 你是对的。我已经编辑了代码,现在应该没问题了。 - Chaouki Anass
难道没有更通用的方式,比如废弃的那种方式吗?一种说“以任何可能的方式连接到互联网”的方式?此外,为什么新的方式没有 isConnectedOrConnecting()?当您调用 hasTransport 时,这是什么意思?是指它本身已连接还是只是连接了? - android developer

3
你可以在官方文档中找到所有信息。

此类已在API级别29中弃用。
调用者应改为使用ConnectivityManager.NetworkCallback API了解网络连接更改情况,或切换使用ConnectivityManager#getNetworkCapabilitiesConnectivityManager#getLinkProperties同步获取信息。请记住,虽然回调保证按顺序调用每个事件,但同步调用没有这样的约束,因此不建议在回调内部使用同步方法,因为它们通常无法提供一致的网络视图(即:它们可能返回与回调处理的事件相比较过去或未来的状态)。相反,建议调用者仅使用回调的参数,并可能记忆从一个回调到另一个回调需要保存的特定信息位。

你可以使用类似以下的内容:

if (connectivityManager != null) {
    if (if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
       NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(connectivityManager.getActiveNetwork());
       if (capabilities != null) {
           if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
               //...
           }
       }
   } else {
     // current code
   }
}

老实说,我已经检查过了,但我需要帮助来设置代码。 - Chaouki Anass
由于您的代码需要API 21,而当前最小值为16,我将只为if(API == 29)放置您的代码请问您可以给我一个条件格式来运行当API等于29时的代码吗? - Chaouki Anass
@ChaoukiAnass 你是对的。在API上添加了条件。 - Gabriele Mariotti
请检查我的新评论。 - Chaouki Anass
1
检查不应该针对Build.VERSION_CODES.Q(API 29)吗? - Cheok Yan Cheng

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接