不推荐使用ConnectivityManager getNetworkInfo(int)

kyl*_*eED 122 networking android android-6.0-marshmallow android-connectivitymanager

使用compileSdkVersion 23,但是尝试支持9到9.

getNetworkInfo(int)在23中已弃用.建议改为使用getAllNetworks和getNetworkInfo(Network).然而,这两者都需要最少的API 21.

我们可以在支持包中使用哪个类可以帮助解决这个问题吗?

我知道之前提出了一个解决方案,但是我对9的最小api要求的挑战造成了问题.

Che*_*ead 156

您可以使用:

getActiveNetworkInfo();

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { 
    // connected to the internet
    if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
        // connected to wifi
    } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
        // connected to mobile data
    }
} else {
    // not connected to the internet
}
Run Code Online (Sandbox Code Playgroud)

或者在开关盒中

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork != null) { 
    // connected to the internet
    switch (activeNetwork.getType()) {
        case ConnectivityManager.TYPE_WIFI:
            // connected to wifi
            break;
        case ConnectivityManager.TYPE_MOBILE:
            // connected to mobile data
            break;
        default:
            break;
    }
} else {
    // not connected to the internet
}
Run Code Online (Sandbox Code Playgroud)

  • 不推荐使用`activeNetwork.getType()`,不推荐使用`ConnectivityManager.TYPE_WIFI` (26认同)
  • 我厌倦了这种不断的弃用周期 (9认同)
  • 从Android 9开始,SDK 28现已弃用. (5认同)
  • 现在替换为`cm.getNetworkCapabilities(cm.activeNetwork).hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)` (4认同)
  • @CheeseBread 这与我发布的代码相同。这个问题的重点是 `getNetworkInfo` 已被弃用:) (3认同)

pav*_*mok 44

至于2018年10月,已接受的答案已被弃用.

getType()和类型本身现在已在API级别28中弃用.来自Javadoc:

呼叫者应切换到使用NetworkCapabilities#TRANSPORT*常量之一检查NetworkCapabilities#hasTransport

要使用NetworkCapabilities,您需要将Network实例传递给getNetworkCapabilities()方法.要获得该实例,您需要调用getActiveNetwork()API Level 23中添加的实例.

所以我现在相信安全检查您是否连接到Wi-Fi或蜂窝网络的正确方法是:

public static boolean isNetworkConnected() {
    final ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (cm != null) {
        if (Build.VERSION.SDK_INT < 23) {
            final NetworkInfo ni = cm.getActiveNetworkInfo();

            if (ni != null) {
                return (ni.isConnected() && (ni.getType() == ConnectivityManager.TYPE_WIFI || ni.getType() == ConnectivityManager.TYPE_MOBILE));
            }
        } else {
            final Network n = cm.getActiveNetwork();

            if (n != null) {
                final NetworkCapabilities nc = cm.getNetworkCapabilities(n);

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

    return false; 
}
Run Code Online (Sandbox Code Playgroud)

您还可以查看其他类型的TRANSPORT,您可以在这里找到.

重要提示:如果您已连接到Wi-Fi VPN,那么您当前的状态可能是TRANSPORT_VPN,因此您可能还想检查它.

不要忘记将以下权限添加到AndroidManifest文件中:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Run Code Online (Sandbox Code Playgroud)


use*_*613 23

该接受的答案又过时28 (Android P),但它的替代方法仅适用于23 (Android M).为了支持旧设备,我编写了一个辅助函数.

如何使用:

int type = getConnectionType(getApplicationContext());
Run Code Online (Sandbox Code Playgroud)

它返回一个int,您可以enum在代码中将其更改为:

0:没有互联网可用(可能在飞机模式下,或在加入Wi-Fi的过程中).

1:移动电话(移动数据,3G/4G/LTE等).

2:Wi-fi.

您可以复制Kotlin或Java版本的辅助函数.

科特林:

@IntRange(from = 0, to = 2)
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) {
        cm?.run {
            cm.getNetworkCapabilities(cm.activeNetwork)?.run {
                if (hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                    result = 2
                } else if (hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = 1
                }
            }
        }
    } else {
        cm?.run {
            cm.activeNetworkInfo?.run {
                if (type == ConnectivityManager.TYPE_WIFI) {
                    result = 2
                } else if (type == ConnectivityManager.TYPE_MOBILE) {
                    result = 1
                }
            }
        }
    }
    return result
}
Run Code Online (Sandbox Code Playgroud)

Java的:

@IntRange(from = 0, to = 2)
public static int getConnectionType(Context context) {
    int result = 0; // Returns connection type. 0: none; 1: mobile data; 2: wifi
    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 = 2;
                } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                    result = 1;
                }
            }
        }
    } else {
        if (cm != null) {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            if (activeNetwork != null) {
                // connected to the internet
                if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                    result = 2;
                } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                    result = 1;
                }
            }
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

  • 我厌倦了这种不断的弃用周期 (13认同)
  • @Christian 如黄色部分所述,此辅助函数返回 3 种可能的状态:“无 Internet”、“蜂窝”和“Wi-Fi”。如果您不关心连接类型,请随意修改代码以适合您的应用程序。 (4认同)
  • 由于您可能有 2 个结果,因此最好使用布尔值而不是返回整数... (2认同)

Nis*_*ara 16

更新回答(19:07:2018):

此方法将帮助您检查互联网连接是否可用.

public static boolean isNetworkAvailable(Context context) {
    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);

    if (connectivityManager != null) {
        NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
        return (activeNetwork != null && activeNetwork.isConnectedOrConnecting());
    } else {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

老答案:

为了最好的代码重用实践,即兴创作奶酪面包答案.

public static boolean isNetworkAvailable(Context context) {
    int[] networkTypes = {ConnectivityManager.TYPE_MOBILE,
            ConnectivityManager.TYPE_WIFI};
    try {
        ConnectivityManager connectivityManager =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        for (int networkType : networkTypes) {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            if (activeNetworkInfo != null &&
                    activeNetworkInfo.getType() == networkType)
                return true;
        }
    } catch (Exception e) {
        return false;
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

代码可以放在Util类中,可用于检查手机是否通过Wifi或移动互联网从应用程序的任何部分连接到Internet.

  • 现在不推荐使用`activeNetwork.isConnectedOrConnecting()` (17认同)
  • 我建议在for循环之外移动活动网络. (3认同)
  • NetworkInfo 现已弃用。需要再次更新! (2认同)

Rah*_*hul 9

可接受的答案在版本28中已弃用,因此这是我在项目中使用的解决方案。

返回连接类型。false:没有Internet连接;true:移动数据|| 无线上网

public static boolean isNetworkConnected(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;
}
Run Code Online (Sandbox Code Playgroud)

  • activeNetwork.getType() 也已弃用。您可以使用 activeNetwork.isConnected(); (3认同)

Nil*_*ore 6

许多答案仍然使用23 以下已弃用的getNetworkType;使用下面的代码检查设备是否有互联网连接。

public static boolean isNetworkConnected(Context context) {

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

    if (cm != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork());
            return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR));
        } else {
            NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
            return activeNetwork != null && activeNetwork.isConnected();
        }
    }

    return false;
}
Run Code Online (Sandbox Code Playgroud)

..

并且,不要忘记在 Manifest 中添加这一行

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Run Code Online (Sandbox Code Playgroud)


Zai*_*ain 5

要检查您是否在线:

boolean isOnline() {
    // Checking internet connectivity
    ConnectivityManager connectivityMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (connectivityMgr != null) {
        activeNetwork = connectivityMgr.getActiveNetworkInfo();
    }
    return activeNetwork != null;
}
Run Code Online (Sandbox Code Playgroud)

获取Android M之前/之后的互联网连接类型

void internetType() {
    // Checking internet connectivity
    ConnectivityManager connectivityMgr = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (connectivityMgr != null) {
        activeNetwork = connectivityMgr.getActiveNetworkInfo();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            NetworkCapabilities nc = connectivityMgr.getNetworkCapabilities(connectivityMgr.getActiveNetwork());
            if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                // connected to mobile data
            } else if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                // connected to wifi
            }
        } else {
            if (activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) {
                // connected to wifi
            } else if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) {
                // connected to mobile data
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所有情况都需要访问网络状态的权限

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Run Code Online (Sandbox Code Playgroud)


Ang*_*i H 5

最好检查您的网络是否连接到 Internet:

@Suppress("DEPRECATION")
fun isNetworkAvailable(context: Context): Boolean {
    try {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return if (Build.VERSION.SDK_INT > 22) {
            val an = cm.activeNetwork ?: return false
            val capabilities = cm.getNetworkCapabilities(an) ?: return false
            capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
        } else {
            val a = cm.activeNetworkInfo ?: return false
            a.isConnected && (a.type == ConnectivityManager.TYPE_WIFI || a.type == ConnectivityManager.TYPE_MOBILE)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return false
}
Run Code Online (Sandbox Code Playgroud)


Der*_*moi 5

这可以帮助某人 Kotlin

fun isNetworkConnected(context: Context) : Boolean {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val capabilities =  connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
        capabilities.also {
            if (it != null){
                if (it.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
                    return true
                else if (it.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)){
                    return true
                }
            }
        }
        return false
    }
Run Code Online (Sandbox Code Playgroud)

  • 可从 API 23+ 获取 (2认同)