ConnectivityManager getNetworkInfo(int)已被弃用。

182

使用compileSdkVersion 23,但尝试支持至少到9。

getNetworkInfo(int)在23中已被弃用。建议使用getAllNetworks()getNetworkInfo(Network)代替。但是这两个都需要最低API 21。

有没有一个可以在支持包中使用的类来帮助解决这个问题?

我知道有一个解决方案before,但是我的最低API要求为9,这是一个问题。


您可以在运行时检查构建版本,并使用适当的方法。 - stinepike
1
这个会不会仍然抛出一个弃用警告? - kyleED
请查看我的ConnectivityObserver类,它封装了Android Nougat以下和以上的API方法。 - JJD
getNetworkInfo(Network)在API级别29中已被弃用。 - cesargastonec
https://dev59.com/JVQJ5IYBdhLWcg3wlm_B#65251284 - Quick learner
28个回答

3

检查互联网是否可用:

@RequiresPermission(allOf = [
    Manifest.permission.ACCESS_NETWORK_STATE, 
    Manifest.permission.INTERNET
])
fun isInternetAvailable(context: Context): Boolean {
    val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
    val activeNetworkInfo = connectivityManager!!.activeNetworkInfo
    return activeNetworkInfo != null && activeNetworkInfo.isConnected
}

3

在 Android M (API 28) 及以下版本中无法找到connectivityManager.getActiveNetwork()方法。

在 Android L 或以上版本中,networkInfo.getState()已被弃用。

因此,最终答案是:

public static boolean isConnectingToInternet(Context mContext) {
    if (mContext == null) return false;

    ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (connectivityManager != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            final Network network = connectivityManager.getActiveNetwork();
            if (network != null) {
                final NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(network);

                return (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                        nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
            }
        } else {
            NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
            for (NetworkInfo tempNetworkInfo : networkInfos) {
                if (tempNetworkInfo.isConnected()) {
                    return true;
                }
            }
        }
    }
    return false;
}

1
你说在 Android M 版本以下找不到 getActiveNetwork() 函数,但是你的代码却在 Lollipop 上使用了它!? - 3c71

3

正如Cheese Bread建议的那样,使用getActiveNetworkInfo()

getActiveNetworkInfo

API 1中添加

NetworkInfo getActiveNetworkInfo ()

返回有关当前活动默认数据网络的详细信息。连接时,此网络是传出连接的默认路由。在启动网络流量之前,您应始终检查isConnected()。当没有默认网络时,这可能返回null。 此方法要求调用者持有ACCESS_NETWORK_STATE权限。 返回值 NetworkInfo 当前默认网络的NetworkInfo对象;如果当前没有默认网络,则为null。

参考:Android Studio

 public final boolean isInternetOn() {

    // get Connectivity Manager object to check connection
    ConnectivityManager connec =
            (ConnectivityManager)getSystemService(getBaseContext().CONNECTIVITY_SERVICE);

    // Check for network connections
    if ( connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.CONNECTED ||
            connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.CONNECTING ) {

        // if connected with internet

        Toast.makeText(this, connec.getActiveNetworkInfo().getTypeName(), Toast.LENGTH_LONG).show();
        return true;

    } else if (
            connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.DISCONNECTED ||
                    connec.getActiveNetworkInfo().getState() == android.net.NetworkInfo.State.DISCONNECTED  ) {

        Toast.makeText(this, " Not Connected ", Toast.LENGTH_LONG).show();
        return false;
    }
    return false;
}

现在调用该方法,为了安全起见,请使用try catch

try {
    if (isInternetOn()) { /* connected actions */ }
    else { /* not connected actions */ }
} catch (Exception e){
  Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}

不要忘记添加:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

谢谢,这很有用。当我们检查网络状态时,如果WiFi和数据都关闭了,应用程序会崩溃,但是使用try catch可以解决这个问题。 - Rucha Bhatt Joshi
然而,如果我想要检查特定类型的网络是否存在并枚举所有存在的网络,即getNetworkInfo(ConnectivityManager.TYPE_ETHERNET).isAvailable,则此方法无法使用。 - m0skit0
3
getState()已被弃用! - Diego Venâncio
几个已弃用的指令! - SMBiggs

2

以下是我如何在最新的Android版本上检查当前网络是否使用蜂窝数据:

val isCellular: Boolean get() {
    val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        cm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
    } else {
        cm.activeNetworkInfo?.type == ConnectivityManager.TYPE_MOBILE
    }
}

2
为了保险起见,我建议同时使用以下方法:

NetworkInfo.isConnected()

完整的方法如下:

/**
 * Checking whether network is connected
 * @param context Context to get {@link ConnectivityManager}
 * @return true if Network is connected, else false
 */
public static boolean isConnected(Context context){
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    if (activeNetwork != null && activeNetwork.isConnected()) {
        int networkType = activeNetwork.getType();
        return networkType == ConnectivityManager.TYPE_WIFI || networkType == ConnectivityManager.TYPE_MOBILE;
    } else {
        return false;
    }
}

10
activeNetwork.getType()已被弃用,ConnectivityManager.TYPE_WIFI也已被弃用。 - noobEinstien

2

我们可能需要多次检查互联网连接。如果我们将代码块编写为Context的扩展方法,那么对我们来说会更容易。以下是我为ContextFragment编写的帮助扩展。

检查互联网连接

最初的回答:

fun Context.hasInternet(): Boolean {
    val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    return if (Build.VERSION.SDK_INT < 23) {
        val activeNetworkInfo = connectivityManager.activeNetworkInfo
        activeNetworkInfo != null && activeNetworkInfo.isConnected
    } else {
        val nc = connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (nc == null) {
            false
        } else {
            nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                    nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
        }
    }
}

其他扩展

fun Context.hasInternet(notifyNoInternet: Boolean = true, trueFunc: (internet: Boolean) -> Unit) {
    if (hasInternet()) {
        trueFunc(true)
    } else if (notifyNoInternet) {
        Toast.makeText(this, "No Internet Connection!", Toast.LENGTH_SHORT).show()
    }
}

fun Context.hasInternet(
    trueFunc: (internet: Boolean) -> Unit,
    falseFunc: (internet: Boolean) -> Unit
) {
    if (hasInternet()) {
        trueFunc(true)
    } else {
        falseFunc(true)
    }
}

fun Fragment.hasInternet(): Boolean = context!!.hasInternet()

fun Fragment.hasInternet(notifyNoInternet: Boolean = true, trueFunc: (internet: Boolean) -> Unit) =
    context!!.hasInternet(notifyNoInternet, trueFunc)

fun Fragment.hasInternet(
    trueFunc: (internet: Boolean) -> Unit, falseFunc: (internet: Boolean) -> Unit
) = context!!.hasInternet(trueFunc, falseFunc)

2

https://www.agnosticdev.com/content/how-detect-network-connectivity-android

请按照这个教程进行操作,它应该能帮助任何寻找答案的人。

注意,networkInfo已经被弃用,因此请使用@vidha下面的答案替换为isNetworkReacheable(), 将getApplicationContext()作为参数传递。

  public static boolean isNetworkReacheable(Context context) {
    boolean result = false;
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (cm != null) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            if (capabilities != null) {
                if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = true;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = true;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = true;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = true;
                }
            }
        }
    }
    return result;
}

2

(几乎)所有答案在Android P中都已被弃用。

Java:

(最初的回答)

public boolean IsOnline(Context context) {
    ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm == null) return false;

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        NetworkInfo ni = cm.getActiveNetworkInfo();

        if (ni == null) return false;

        return ni.isConnected() && (ni.getType() == ConnectivityManager.TYPE_WIFI || ni.getType() == ConnectivityManager.TYPE_MOBILE);
    }

    NetworkCapabilities nc = cm.getNetworkCapabilities(cm.getActiveNetwork());

    if (nc == null) return false;

    return nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
}

C#:

public bool IsOnline(Context context)
{
    var cm = (ConnectivityManager)context.GetSystemService(Context.ConnectivityService);
   
    if (cm == null) return false;

    if (Build.VERSION.SdkInt < BuildVersionCodes.M)
    {
        var ni = cm.ActiveNetworkInfo;

        if (ni == null) return false;

        return ni.IsConnected && (ni.Type == ConnectivityType.Wifi || ni.Type == ConnectivityType.Mobile);
    }

    return cm.GetNetworkCapabilities(cm.ActiveNetwork).HasTransport(Android.Net.TransportType.Wifi)
        || cm.GetNetworkCapabilities(cm.ActiveNetwork).HasTransport(Android.Net.TransportType.Cellular);
}   

关键在于NetworkCapabilities.TRANSPORT_XXXAndroid.Net.TransportType)。最初的回答。

1
这里的所有内容都已经过时了! - Prescott Chartier
1
@PrescottChartier 是哪个版本? - Mehdi Dehghani

2

这也适用于Android 10。如果连接到互联网,则返回true,否则返回false。

private fun isOnline(): Boolean {
        val connectivityManager =
                getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val capabilities =
                connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        if (capabilities != null) {
            when {
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR")
                    return true
                }
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI")
                    return true
                }
                capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> {
                    Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET")
                    return true
                }
            }
        }
        return false
    }

从API 23+可用 - martinseal1987

2

以下代码适用于所有API。(Kotlin)

然而,getActiveNetworkInfo()仅在API 29中已被弃用,并适用于所有低于29的API,因此我们可以在所有低于29的API中使用它。

fun isInternetAvailable(context: Context): Boolean {
            var result = false
            val connectivityManager =
                context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                val networkCapabilities = connectivityManager.activeNetwork ?: return false
                val actNw =
                    connectivityManager.getNetworkCapabilities(networkCapabilities) ?: return false
                result = when {
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    actNw.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                    else -> false
                }
            } else {
                connectivityManager.run {
                    connectivityManager.activeNetworkInfo?.run {
                        result = when (type) {
                            ConnectivityManager.TYPE_WIFI -> true
                            ConnectivityManager.TYPE_MOBILE -> true
                            ConnectivityManager.TYPE_ETHERNET -> true
                            else -> false
                        }

                    }
                }
            }

            return result
        }

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