核心概念
在开始之前,需要理解几个核心概念:

-
网络连接类型:
ConnectivityManager: 这是 Android 系统中管理所有网络连接的核心类,通过它可以查询可用的网络、网络状态等。NetworkCapabilities: 这是 Android 7.0 (API 24) 引入的新概念,用来描述一个网络的能力,比如是否有互联网连接、是否是漫游、是否是_metered(按流量计费)等。NetworkInfo: 这是旧版本使用的类,用于描述网络信息,如类型(移动、Wi-Fi)、状态(连接中、已连接、断开等)。在 Android 10 (API 29) 中已被废弃。
-
网络权限:
- 要访问网络状态,必须在
AndroidManifest.xml中声明网络权限。 - 对于现代 Android 版本(API 28+),建议使用
ACCESS_NETWORK_STATE权限,它比INTERNET权限更精确,只允许应用查询网络状态,而不是访问网络。
- 要访问网络状态,必须在
使用 ConnectivityManager (推荐,适用于所有版本)
这是最主流和官方推荐的方法,我们将根据 Android 版本的不同,展示如何使用它。
第 1 步:添加权限
在 app/src/main/AndroidManifest.xml 文件中添加以下权限:

<!-- 允许应用访问网络状态信息 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 如果你的应用需要连接网络,还需要这个权限 --> <uses-permission android:name="android.permission.INTERNET" />
第 2 步:编写代码
检查是否有网络连接 (通用方法)
这个方法可以检查设备是否连接到了某个网络,但不一定是可用的互联网。
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
public class NetworkUtils {
/**
* 检查是否有任何网络连接
* @param context 上下文
* @return true 表示有网络连接,false 表示没有
*/
public static boolean isNetworkConnected(Context context) {
if (context != null) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
// 在旧版本中,使用 getActiveNetworkInfo()
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
if (activeNetworkInfo != null) {
return activeNetworkInfo.isConnected();
}
}
return false;
}
}
检查是否有可用的互联网连接 (推荐)
仅仅连接到网络不代表可以上网(连接到了一个没有外网的 Wi-Fi),更可靠的方法是检查网络是否具有 INTERNET 能力。
对于 Android 7.0 (API 24) 及以上版本:
这是现代 Android 开发的首选方式。

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkRequest;
import androidx.annotation.NonNull;
public class NetworkUtils {
/**
* 检查是否有可用的互联网连接 (API 24+)
* @param context 上下文
* @return true 表示有可用的互联网连接,false 表示没有
*/
public static boolean isInternetAvailable(Context context) {
if (context == null) {
return false;
}
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
// 在 Android 10 (API 29) 及以上,getActiveNetwork() 是推荐方法
Network network = connectivityManager.getActiveNetwork();
if (network == null) {
return false;
}
// 获取网络的能力
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities == null) {
return false;
}
// 检查网络是否具备互联网连接能力
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) &&
capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
}
}
对于 Android 6.0 (API 23) 及以下版本:
如果需要兼容旧版本,可以结合使用 NetworkInfo 和 NetworkCapabilities 的方式。
// 在同一个 NetworkUtils 类中添加这个方法
public static boolean isInternetAvailableLegacy(Context context) {
if (context == null) {
return false;
}
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
// 1. 首先尝试使用新方法 (API 23+)
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Network network = connectivityManager.getActiveNetwork();
if (network != null) {
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities != null && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
return true;
}
}
}
// 2. 如果新方法不可用,则回退到旧方法 (API 23-)
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected() && activeNetworkInfo.isAvailable();
}
获取具体的网络类型 (Wi-Fi, 移动数据等)
对于 Android 7.0 (API 24) 及以上版本:
public static String getNetworkType(Context context) {
if (context == null) {
return "Unknown";
}
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
Network network = connectivityManager.getActiveNetwork();
if (network == null) {
return "No Network";
}
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
if (capabilities == null) {
return "Unknown";
}
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 "Unknown";
}
对于 Android 6.0 (API 23) 及以下版本:
// 在同一个 NetworkUtils 类中添加这个方法
public static String getNetworkTypeLegacy(Context context) {
if (context == null) {
return "Unknown";
}
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
if (activeNetworkInfo == null || !activeNetworkInfo.isConnected()) {
return "No Network";
}
int type = activeNetworkInfo.getType();
switch (type) {
case ConnectivityManager.TYPE_WIFI:
return "Wi-Fi";
case ConnectivityManager.TYPE_MOBILE:
return "Mobile";
case ConnectivityManager.TYPE_ETHERNET:
return "Ethernet";
default:
return "Unknown";
}
}
监听网络状态变化
很多时候,你需要在网络状态改变时(从 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);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
// 设置监听的网络能力
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// 对于 Android 7.0+,可以指定网络类型
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
// builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
}
NetworkRequest networkRequest = builder.build();
// 创建回调
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(@NonNull Network network) {
// 网络变为可用时调用
Log.d("NetworkMonitor", "Network is available!");
// 在这里执行网络恢复后的操作,比如重新加载数据
}
@Override
public void onLost(@NonNull Network network) {
// 网络丢失时调用
Log.d("NetworkMonitor", "Network is lost!");
// 在这里执行网络丢失后的操作,比如停止下载
}
@Override
public void onUnavailable() {
// 没有任何可用网络时调用
Log.d("NetworkMonitor", "No available network!");
}
};
// 注册回调
connectivityManager.registerNetworkCallback(networkRequest, networkCallback);
}
public void unregister() {
if (connectivityManager != null && networkCallback != null) {
connectivityManager.unregisterNetworkCallback(networkCallback);
networkCallback = null;
}
}
}
在 Activity/Service 中使用
public class MainActivity extends AppCompatActivity {
private NetworkMonitor networkMonitor;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
networkMonitor = new NetworkMonitor();
}
@Override
protected void onStart() {
super.onStart();
// 在 Activity 可见时开始监听
networkMonitor.register(this);
}
@Override
protected void onStop() {
super.onStop();
// 在 Activity 不可见时停止监听,防止内存泄漏
networkMonitor.unregister();
}
}
总结与最佳实践
- 权限是基础:别忘了在
AndroidManifest.xml中声明ACCESS_NETWORK_STATE权限。 - 版本适配是关键:
- 目标 API 29+:应完全使用
ConnectivityManager.getActiveNetwork()和NetworkCapabilities。 - 需要兼容旧版:使用
Build.VERSION.SDK_INT进行判断,优先使用新 API,失败后回退到NetworkInfo。
- 目标 API 29+:应完全使用
- 功能区分:
- 想知道 是否连接到网络,用
isNetworkConnected。 - 想知道 是否能上网,用
isInternetAvailable,这是更可靠的方式。 - 想知道 网络的具体类型,用
getNetworkType。 - 想在 网络变化时响应,用
NetworkCallback。
- 想知道 是否连接到网络,用
- 生命周期管理:
NetworkCallback的注册和注销要与组件的生命周期(如Activity的onStart/onStop)绑定,避免内存泄漏和不必要的资源消耗。
希望这份详细的指南能帮助你完美地在 Android 应用中处理网络状态!
