【问题标题】:getActiveNetworkInfo() is deprecated in API 29 [duplicate]getActiveNetworkInfo() 在 API 29 中已弃用 [重复]
【发布时间】:2019-07-30 18:15:07
【问题描述】:

我正在使用一个代码来检查用户是否有互联网活动,但是在针对 sdk29 之后,下面的功能被弃用了

网络信息

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;
}

【问题讨论】:

标签: android


【解决方案1】:

基于Google Document已弃用

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

所以,如果你想找到网络连接状态,你可以使用这个代码。

科特林:

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:

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

【讨论】:

  • 我认为我们必须添加 capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET
  • @ChaoukiAnass 我认为我们需要添加互联网连接工具,对于移动用户,他们能够通过 wifi 或蜂窝网络连接到互联网,但如果您认为有必要,我可以。
  • 它是否适用于蓝牙或 USB 网络共享?
  • @Francis 对于蓝牙,我们可以添加 NetworkCapabilities.TRANSPORT_BLUETOOTH。但对于 USB 网络共享我不确定。但试试这个 NET_CAPABILITY_DUN。
  • 不应该对 Build.VERSION_CODES.Q (API 29) 进行检查吗?
【解决方案2】:

我终于找到了适用于所有 API 的代码,以防万一有人需要它

NetworkCapabilities 在 API 29 中没有被弃用,但它需要 API 21,所以我只在 API 29 上调用了它。

但是 getActiveNetworkInfo() 仅在 API 29 中被弃用,并且适用于所有 API,因此我们可以在下面的所有 API 中使用它 29

这是代码

    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 为什么它会在 Android R 上中断? PS:请检查我对以太网电缆的编辑
  • android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.Q 这意味着新函数只会在 Android Q 中调用,而不是 Android Q 或更高版本。 Android R 将调用旧的、过时的函数,因为 if 语句将落入 else!
  • @Zun 你是对的。我已经编辑了我想现在一切正常的代码
  • 没有更通用的方法吗,比如不推荐使用的方法?一个说“以任何可能的方式连接到互联网”?另外,为什么新方法没有 isConnectedOrConnecting() ?当您拨打 hasTransport 时是什么意思?是这个,还是单独连接的?
【解决方案3】:

您可以在official doc找到所有信息

此类已在 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
   }
}

【讨论】:

  • 老实说我已经检查过了,我需要帮助来设置代码
  • 由于您的代码需要 API 21 并且当前最小值为 16,因此我将您的代码用于 if (API == 29) 如果 API 等于 29,您是否介意给我运行代码的条件格式跨度>
  • @ChaoukiAnass 你是对的。在 api 上添加条件。
  • 请查看我的新评论
  • 不应该对 Build.VERSION_CODES.Q (API 29) 进行检查吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-09
  • 2019-11-20
  • 1970-01-01
  • 2019-11-01
  • 2013-09-01
  • 2020-01-21
  • 2013-08-22
相关资源
最近更新 更多