睿诚科技协会

Android如何彻底关闭网络?

概览:关闭网络的不同场景

场景 目标 方法 难度 需要权限
临时关闭设备网络 整个手机(Wi-Fi 和移动数据) 系统设置快捷开关飞行模式 非常简单
仅关闭 Wi-Fi 整个手机的 Wi-Fi 连接 系统设置快捷开关 非常简单
仅关闭移动数据 整个手机的移动数据连接 系统设置快捷开关 非常简单
在 App 内禁用网络 自己 App 的所有网络请求 ConnectivityManager API 中等 INTERNET (普通)
控制/禁用其他 App 的网络 特定 App 的网络访问 ADB 命令系统级开发 SYSTEM (系统级)
开发时模拟网络关闭 用于测试 App 的网络容错能力 Android Studio 模拟器ADB 命令 简单

临时关闭设备网络(用户手动操作)

这是最常见的需求,用户可以直接通过手机设置来操作。

Android如何彻底关闭网络?-图1
(图片来源网络,侵删)

方法 1:使用飞行模式(最彻底)

飞行模式会同时关闭 Wi-Fi、蓝牙、移动数据、GPS 等所有无线信号。

  • 操作路径:从屏幕顶部向下滑动,拉出通知栏,找到并点击“飞行模式”图标(通常是一个飞机的标志),再次点击即可关闭。

方法 2:仅关闭 Wi-Fi

如果您只需要断开 Wi-Fi 网络,保留移动数据。

  • 操作路径:从屏幕顶部向下滑动,拉出通知栏,找到并点击“Wi-Fi”图标,使其变为灰色。

方法 3:仅关闭移动数据

如果您只想禁用移动数据(流量),使用 Wi-Fi 时不受影响。

  • 操作路径
    1. 从屏幕顶部向下滑动,拉出通知栏。
    2. 长按“Wi-Fi”或“移动数据”图标,进入快速设置面板。
    3. 在移动数据区域,点击开关图标将其关闭。

方法 4:通过系统设置菜单

您也可以进入手机的“设置”应用进行更详细的配置。

Android如何彻底关闭网络?-图2
(图片来源网络,侵删)
  • Wi-Fi设置 -> 网络和互联网 -> Wi-Fi
  • 移动数据设置 -> 网络和互联网 -> 移动网络

在 App 内禁用自己 App 的网络(开发者)

如果您是 Android 开发者,想在自己的 App 内实现网络开关功能(省流量模式”),可以使用 ConnectivityManager API。

核心思路

  1. 获取 ConnectivityManager 系统服务。
  2. 检查当前网络状态。
  3. 根据用户操作,设置网络请求的策略,注意:现代 Android 版本无法直接“关闭”网络,而是需要通过 setProcessDefaultNetwork(null) 来取消当前绑定的网络,让后续请求失败,从而达到类似“关闭”的效果。

示例代码

import android.content.Context
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.os.Build
import android.util.Log
object NetworkUtils {
    private const val TAG = "NetworkUtils"
    // 检查网络是否可用
    fun isNetworkAvailable(context: Context): Boolean {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val network = connectivityManager.activeNetwork
            val capabilities = connectivityManager.getNetworkCapabilities(network)
            return capabilities != null && (
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) ||
                            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) ||
                            capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)
                    )
        } else {
            // 对于旧版本,使用 deprecated 方法
            @Suppress("DEPRECATION")
            val networkInfo = connectivityManager.activeNetworkInfo
            return networkInfo != null && networkInfo.isConnected
        }
    }
    // 在 App 内部“禁用”网络(实际是解绑网络)
    fun disableNetwork(context: Context) {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        // API 24+ 的方法,将进程的默认网络设置为 null
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            connectivityManager.bindProcessToNetwork(null)
            Log.d(TAG, "App network has been disabled.")
        } else if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            // 对于 API 21 - 23
            @Suppress("DEPRECATION")
            connectivityManager.bindProcessToNetwork(null)
            Log.d(TAG, "App network has been disabled.")
        } else {
            Log.e(TAG, "Cannot disable network on this API level.")
        }
    }
    // 在 App 内部“启用”网络(重新绑定到当前可用网络)
    fun enableNetwork(context: Context) {
        val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // 重新绑定到当前活动的网络
            connectivityManager.bindProcessToNetwork(connectivityManager.activeNetwork)
            Log.d(TAG, "App network has been enabled.")
        } else if (Build.VERSION_CODES.LOLLIPOP <= Build.VERSION.SDK_INT && Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            @Suppress("DEPRECATION")
            connectivityManager.bindProcessToNetwork(connectivityManager.activeNetworkInfo)
            Log.d(TAG, "App network has been enabled.")
        } else {
            Log.e(TAG, "Cannot enable network on this API level.")
        }
    }
}

注意

  • 此方法仅对调用它的 App 进程有效,不会影响其他 App。
  • 在 Android 10 (API 29) 及更高版本中,为了增强隐私和安全,对后台网络访问有更严格的限制,此方法的行为也受到这些策略的约束。

控制或禁用其他 App 的网络(高级/系统级)

普通 App 绝对没有权限去关闭其他 App 的网络。 这是一项高风险操作,通常只有系统应用或拥有特殊权限的设备制造商才能实现。

方法:使用 ADB (Android Debug Bridge) - 主要用于开发者测试

如果您是开发者或高级用户,并已开启 USB 调试,可以使用 ADB 来模拟某个应用的网络状态。

Android如何彻底关闭网络?-图3
(图片来源网络,侵删)
  1. 开启 USB 调试:在开发者选项中开启。

  2. 连接电脑:使用 USB 线连接手机和电脑。

  3. 执行命令

    • 禁止网络访问

      # 命令格式:adb shell cmd connectivity disable-inet-uid <UID>
      # 首先需要获取目标 App 的 UID
      adb shell dumpsys package <package.name> | grep "PackageSignatures"
      # 假设获取到的 UID 是 10155
      # 然后执行禁用命令
      adb shell cmd connectivity disable-inet-uid 10155

      这条命令会告诉系统,禁止 UID 为 10155 的应用进程访问网络。

    • 恢复网络访问

      adb shell cmd connectivity enable-inet-uid 10155

注意:此方法主要用于测试,普通用户不应尝试,因为需要知道目标应用的 UID,且操作不当可能影响系统稳定性。


开发时模拟网络关闭(开发者)

在开发 App 时,您经常需要测试“无网络”或“网络差”的场景。

方法 1:使用 Android Studio 模拟器

Android 模拟器提供了强大的网络控制功能。

  1. 打开模拟器的“扩展控制面板”(点击模拟器右侧的 图标)。
  2. 切换到 Virtual sensors 标签页。
  3. Network 部分,您可以:
    • 选择网络类型:如 2G, 3G, 4G, Wi-Fi 等。
    • 模拟网络延迟和丢包:拖动滑块来模拟网速慢或不稳定的网络。
    • 完全断开网络:选择 "Disabled"。

方法 2:使用 ADB 命令

ADB 提供了更底层的网络模拟方式。

  • 完全禁用模拟器网络
    adb shell svc wifi disable
    adb shell svc data disable
  • 重新启用模拟器网络
    adb shell svc wifi enable
    adb shell svc data enable
  • 模拟网络延迟(需要 tc 命令支持):
    # 添加 2000ms (2秒) 的延迟
    adb shell tc qdisc add dev wlan0 root netem delay 2000ms
    # 清除延迟
    adb shell tc qdisc del dev wlan0 root
你的需求 推荐方案
我只是想自己手机断网 使用 通知栏的快捷开关(飞行模式/Wi-Fi/移动数据)。
我想在我的 App 里做个省流量开关 使用 ConnectivityManagerbindProcessToNetwork(null) 方法。
我想测试我的 App 在没网时的情况 使用 Android Studio 模拟器的网络控制ADB 命令
我想让某个特定的 App 上不了网 这通常无法实现,除非你是开发者用 ADB 测试,或你有系统级权限。

希望这份详细的指南能帮助您解决问题!

分享:
扫描分享到社交APP
上一篇
下一篇