- 连接状态:设备是否连接到了网络(任何类型)。
- 网络类型:设备连接的是哪种具体的网络,如 Wi-Fi、移动数据(2G/3G/4G/5G)、以太网等。
下面我将详细介绍如何实现这两种判断,并提供完整的代码示例。

使用 ConnectivityManager (传统方法,API 26+ 推荐)
这是 Android 官方推荐的标准方法,特别是从 Android 8.0 (API 26) 开始,NetworkCapabilities 成为了获取网络信息的主要方式。
添加网络权限
在 AndroidManifest.xml 中必须声明网络访问权限。
<!-- 允许应用完全访问网络 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 从 Android 9 (API 28) 开始,如果应用使用 cleartext traffic (如 HTTP),需要显式声明 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
判断网络连接状态 (是否联网)
这个方法可以判断设备是否有任何可用的网络连接。
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
public class NetworkUtils {
/**
* 检查设备是否有任何可用的网络连接
* @param context 上下文
* @return true 有网络,false 无网络
*/
public static boolean isNetworkAvailable(Context context) {
if (context == null) {
return false;
}
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
// 从 Android 10 (API 29) 开始,推荐使用 getDefaultNetwork()
Network network = connectivityManager.getActiveNetwork();
if (network != null) {
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities != null) {
// 只要满足以下任意一种,就认为有网络连接
return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) ||
capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH);
}
}
}
return false;
}
}
判断具体的网络类型
要判断是 Wi-Fi、移动数据还是其他类型,我们需要检查 NetworkCapabilities 中的 TRANSPORT 类型。

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
public class NetworkUtils {
// ... isNetworkAvailable 方法如上 ...
/**
* 获取当前网络类型
* @param context 上下文
* @return 网络类型字符串 (Wi-Fi, Mobile, Ethernet, None)
*/
public static String getNetworkType(Context context) {
if (context == null) {
return "None";
}
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
Network network = connectivityManager.getActiveNetwork();
if (network != null) {
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
return "Wi-Fi";
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return "Mobile";
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
return "Ethernet";
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)) {
return "Bluetooth";
}
}
}
}
return "None";
}
}
监听网络状态变化
网络状态不是一成不变的,当 Wi-Fi 断开或切换到移动数据时,你的应用需要知道,可以通过 NetworkCallback 来实现。
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import android.os.Build;
public class NetworkMonitor {
private ConnectivityManager.NetworkCallback networkCallback;
private ConnectivityManager connectivityManager;
public void register(Context context) {
connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager == null) return;
NetworkRequest request = new NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.build();
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
// 网络可用时调用
// 可以在这里调用 NetworkUtils.getNetworkType() 获取类型
String networkType = NetworkUtils.getNetworkType(context);
// ... 你的逻辑 ...
}
@Override
public void onLost(Network network) {
// 网络丢失时调用
// ... 你的逻辑 ...
}
@Override
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
// 网络能力改变时调用(从 4G 切换到 5G)
// ... 你的逻辑 ...
}
};
// 注册回调
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(networkCallback);
} else {
// 对于 N 以下的版本,需要使用 registerNetworkCallback
connectivityManager.registerNetworkCallback(request, networkCallback);
}
}
public void unregister() {
if (connectivityManager != null && networkCallback != null) {
connectivityManager.unregisterNetworkCallback(networkCallback);
}
}
}
使用 NetworkMonitor:
在你的 Activity 或 Service 的生命周期中管理它。
public class MyActivity extends AppCompatActivity {
private NetworkMonitor networkMonitor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
networkMonitor = new NetworkMonitor();
}
@Override
protected void onResume() {
super.onResume();
networkMonitor.register(this);
}
@Override
protected void onPause() {
super.onPause();
networkMonitor.unregister();
}
}
使用 TelephonyManager (获取移动网络详细类型)
ConnectivityManager 可以告诉你当前是 "Mobile",但无法区分是 2G, 3G, 4G 还是 5G,要获取这些详细的移动网络信息,需要使用 TelephonyManager。

添加权限
TelephonyManager 是敏感 API,需要声明权限。
<!-- 获取网络状态信息 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 从 Android 10 (API 29) 开始,需要 READ_PHONE_STATE 来获取网络信息 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
获取详细网络类型
import android.annotation.SuppressLint;
import android.content.Context;
import android.telephony.TelephonyManager;
public class MobileNetworkUtils {
@SuppressLint("MissingPermission") // 注意:实际开发中需要处理权限
public static String getMobileNetworkType(Context context) {
if (context == null) {
return "Unknown";
}
TelephonyManager telephonyManager = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager == null) {
return "Unknown";
}
// 从 Android 9 (API 28) 开始,getNetworkType() 已弃用,推荐使用 getNetworkType()
// 但新方法需要 READ_PHONE_STATE 权限
int networkType = telephonyManager.getNetworkType();
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_CDMA:
return "2G";
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
return "3G";
case TelephonyManager.NETWORK_TYPE_LTE:
return "4G";
case TelephonyManager.NETWORK_TYPE_NR:
return "5G";
default:
return "Unknown";
}
}
}
注意权限问题:在 Android 6.0 (API 23) 及以上版本,
READ_PHONE_STATE是一个危险权限,必须在运行时动态请求,否则会抛出SecurityException。
总结与最佳实践
| 需求 | 推荐API | 关键类/方法 | 说明 |
|---|---|---|---|
| 判断是否联网 | ConnectivityManager |
getActiveNetwork(), getNetworkCapabilities() |
官方标准方法,适用于所有 Android 版本。 |
| 判断网络大类 | ConnectivityManager |
NetworkCapabilities.hasTransport() |
可区分 Wi-Fi, Mobile, Ethernet 等。 |
| 判断移动网络子类 | TelephonyManager |
getNetworkType() |
可区分 2G, 3G, 4G, 5G,需要 READ_PHONE_STATE 权限。 |
| 监听网络变化 | ConnectivityManager |
registerDefaultNetworkCallback() |
实时响应网络状态变化,是现代 Android 应用的首选。 |
完整逻辑建议:
- 首选
ConnectivityManager:用它来判断是否有网络以及网络的大类别(Wi-Fi/Mobile)。 - 使用
TelephonyManager增强信息:当确定当前是移动网络时,再调用TelephonyManager来获取更详细的 4G/5G 信息。 - 注册
NetworkCallback:在应用启动时注册一个全局的网络监听器,以便在后台也能及时响应网络变化。 - 处理权限:务必处理好
READ_PHONE_STATE权限的申请和检查。
