Android 获取网络连接状态新方法
一. 问题背景
Android12上,有的app模块判断当前网络的类型和连接状态时,还是使用的旧的API,导致返回的结果不准确,影响代码逻辑判断,本篇文章就这一问题,整理一下判断网络类型和连接状态的新方法。
二. 原因分析
在Android 10以前的版本,大家都是通过NetworkInfo.java 的getType()方法获取网络类型,通过isConnected()方法来判断是否连接上, 判断网络连接的旧方法如下:
1.是否连接:

2. 网络类型

但是在Android10之后,这些方法已过时,官方不推荐使用,我们先来看下官方的源码说明


左边是Android10,右边是Android9的源码 , 在10上已经标记Deprecated,新加的注释也推荐了使用的API。
还有一个旧广播String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE" 在Android 9之后也废弃,不推荐使用,之前的使用方法:

看下官方说明:

官方标记Deprecated,是避免在高版本的设备上获取返回的网络状态不对,并且给了推荐的API,以Android10为一个分界点, 之后的版本都推荐使用新的API方法。
三. 官方推荐API
官方推荐:监控 Android 中的互联网连接,可以使用ConnectivityManager类,这是一个允许您查询网络状态的系统服务类, 还有一个NetworkCapabilities类,代表活动网络的功能。

体使用方法如下:
registerNetworkCallback():此函数注册一个NetworkCallback对象来监听网络状态变化。它以一个NetworkCallback对象作为参数。
unregisterNetworkCallback():此函数取消注册以前注册的NetworkCallback对象。
接下来重点关注NetworkCallback中的回调方法描述
| 回调方法 | 描述 |
| onCapabilitiesChanged | 当网络状态改变 但仍旧是可用状态时调用 |
| onAvailable | 网络连接成功,通知可以使用的时候调用 |
| onUnavailable | 当网络连接超时或网络请求达不到可用要求时调用 |
| onBlockedStatusChanged | 当访问指定的网络被阻止或解除阻塞时调用 |
| onLosing | 当网络正在断开连接时调用 |
| onLost | 当网络已断开连接时调用 |
| onLinkPropertiesChanged | 当网络连接的属性被修改时调用 |
接下来再说一下
NetworkCapabilities.java类中的NET_CAPABILITY_VALIDATED字段,描述为:
表示此网络上的连接已成功验证。例如,对于具有NET_CAPABILITY_INTERNET的网络,这意味着已成功检测到INTERNET连接。
通过实际log来描述说明一下:
1. 连接上可上网的wifi,可看到VALIDATED的标记:
![]()
2. 连接上需要认证和不能上网的wifi,找不到VALIDATED标记:
![]()
3. 用数据流量上网,可以看到VALIDATED的标记:
![]()
我们可以通过networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)这个方法作为(连接可以正常上网的网络)判断条件。进一步通过networkCapabilities.hasTransport方法来判断当前的网络类型。

四. 使用方法
看代码更直接一点:
MainActivity.java
@SuppressLint("NewApi")
public class MainActivity extends AppCompatActivity {private static final String TAG = "ConnectManager";private ConnectivityManager networkService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);networkService = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);if (networkService != null) {//注册 NetworkCallBacknetworkService.registerDefaultNetworkCallback(networkCallBack);}}/** 测试网络工具类方法* */@Overrideprotected void onResume() {super.onResume();//Log.e(TAG, "=====在onResume方法中判断 : isMobileNetwork :" + NetworkUtils.isMobileNetwork(this));//Log.e(TAG, "=====在onResume方法中判断 : isWifiNetwork :" + NetworkUtils.isWifiNetwork(this));//Log.e(TAG, "=====在onResume方法中判断 : getConnectedNetworkType :" + NetworkUtils.getConnectedNetworkType(this));}@Overrideprotected void onDestroy() {super.onDestroy();if (networkService != null && networkCallBack != null) {networkService.unregisterNetworkCallback(networkCallBack);}}private final ConnectivityManager.NetworkCallback networkCallBack = new ConnectivityManager.NetworkCallback(){//当网络状态修改但仍旧是可用状态时调用@Overridepublic void onCapabilitiesChanged(@NonNull Network network, @NonNull NetworkCapabilities networkCapabilities) {super.onCapabilitiesChanged(network, networkCapabilities);if (NetworkUtils.isConnectedAvailableNetwork(getBaseContext())) {Log.d(TAG, "onCapabilitiesChanged ---> ====网络可正常上网===网络类型为: "+ NetworkUtils.getConnectedNetworkType(MainActivity.this));}//表明此网络连接验证成功if(networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {Log.d(TAG, "===当前在使用Mobile流量上网===");} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {Log.d(TAG, "====当前在使用WiFi上网===");} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)) {Log.d(TAG, "=====当前使用蓝牙上网=====");} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {Log.d(TAG, "=====当前使用以太网上网=====");} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {Log.d(TAG, "===当前使用VPN上网====");} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE)) {Log.d(TAG, "===表示此网络使用Wi-Fi感知传输====");} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN)) {Log.d(TAG, "=====表示此网络使用LoWPAN传输=====");} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_USB)) {Log.d(TAG, "=====表示此网络使用USB传输=====");}}}@Overridepublic void onAvailable(@NonNull Network network) {super.onAvailable(network);Log.e(TAG, "==网络连接成功,通知可以使用的时候调用====onAvailable===");}@Overridepublic void onUnavailable() {Log.e(TAG, "==当网络连接超时或网络请求达不到可用要求时调用====onUnavailable===");super.onUnavailable();}@Overridepublic void onBlockedStatusChanged(@NonNull Network network, boolean blocked) {Log.e(TAG, "==当访问指定的网络被阻止或解除阻塞时调用===onBlockedStatusChanged==");super.onBlockedStatusChanged(network, blocked);}@Overridepublic void onLosing(@NonNull Network network, int maxMsToLive) {Log.e(TAG, "==当网络正在断开连接时调用===onLosing===");super.onLosing(network, maxMsToLive);}@Overridepublic void onLost(@NonNull Network network) {Log.e(TAG, "==当网络已断开连接时调用===onLost===");super.onLost(network);}@Overridepublic void onLinkPropertiesChanged(@NonNull Network network, @NonNull LinkProperties linkProperties) {Log.e(TAG, "==当网络连接的属性被修改时调用===onLinkPropertiesChanged===");super.onLinkPropertiesChanged(network, linkProperties);}};}
网络工具类NetworkUtils.java
@SuppressLint("NewApi")
public class NetworkUtils {private static final String TAG = "ConnectManager";/*** Indicates this network uses a Cellular transport.*/public static final int TRANSPORT_CELLULAR = 0;/*** Indicates this network uses a Wi-Fi transport.*/public static final int TRANSPORT_WIFI = 1;/*** Indicates this network uses a Bluetooth transport.*/public static final int TRANSPORT_BLUETOOTH = 2;/*** Indicates this network uses an Ethernet transport.*/public static final int TRANSPORT_ETHERNET = 3;/*** Indicates this network uses a VPN transport.*/public static final int TRANSPORT_VPN = 4;/*** Indicates this network uses a Wi-Fi Aware transport.*/public static final int TRANSPORT_WIFI_AWARE = 5;/*** Indicates this network uses a LoWPAN transport.*/public static final int TRANSPORT_LOWPAN = 6;/*** Indicates this network uses a Test-only virtual interface as a transport.* @hide*/public static final int TRANSPORT_TEST = 7;/*** Indicates this network uses a USB transport.*/public static final int TRANSPORT_USB = 8;/*** >= Android 10(Q版本)推荐** 当前使用MOBILE流量上网*/public static boolean isMobileNetwork(Context context) {ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);Network network = cm.getActiveNetwork();if (null == network) {return false;}NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);if (null == capabilities) {return false;}return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);}/*** >= Android 10(Q版本)推荐** 当前使用WIFI上网*/public static boolean isWifiNetwork(Context context) {ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);Network network = cm.getActiveNetwork();if (null == network) {return false;}NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);if (null == capabilities) {return false;}return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);}/*** >= Android 10(Q版本)推荐** 当前使用以太网上网*/public static boolean isEthernetNetwork(Context context) {ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);Network network = cm.getActiveNetwork();if (null == network) {return false;}NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);if (null == capabilities) {return false;}return capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);}/*** >= Android 10(Q版本)推荐** NetworkCapabilities.NET_CAPABILITY_INTERNET,表示此网络应该(maybe)能够访问internet** 判断当前网络可以正常上网* 表示此连接此网络并且能成功上网。 例如,对于具有NET_CAPABILITY_INTERNET的网络,这意味着已成功检测到INTERNET连接。*/public static boolean isConnectedAvailableNetwork(Context context) {ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);Network network = cm.getActiveNetwork();if (null == network) {return false;}NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);if (null == capabilities) {return false;}return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)&& capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);}/*** >= Android 10(Q版本)推荐** 获取成功上网的网络类型* value = {* TRANSPORT_CELLULAR, 0 表示此网络使用蜂窝传输。* TRANSPORT_WIFI, 1 表示此网络使用Wi-Fi传输。* TRANSPORT_BLUETOOTH, 2 表示此网络使用蓝牙传输。* TRANSPORT_ETHERNET, 3 表示此网络使用以太网传输。* TRANSPORT_VPN, 4 表示此网络使用VPN传输。* TRANSPORT_WIFI_AWARE, 5 表示此网络使用Wi-Fi感知传输。* TRANSPORT_LOWPAN, 6 表示此网络使用LoWPAN传输。* TRANSPORT_TEST, 7 指示此网络使用仅限测试的虚拟接口作为传输。* TRANSPORT_USB, 8 表示此网络使用USB传输* }*/public static int getConnectedNetworkType(Context context) {ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);Network network = cm.getActiveNetwork();if (null == network) {return -1;}NetworkCapabilities capabilities = cm.getNetworkCapabilities(network);if (null == capabilities) {return -1;}if (capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {return NetworkCapabilities.TRANSPORT_CELLULAR;} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {return NetworkCapabilities.TRANSPORT_WIFI;} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_BLUETOOTH)) {return NetworkCapabilities.TRANSPORT_BLUETOOTH;} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {return NetworkCapabilities.TRANSPORT_ETHERNET;} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {return NetworkCapabilities.TRANSPORT_VPN;} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI_AWARE)) {return NetworkCapabilities.TRANSPORT_WIFI_AWARE;} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_LOWPAN)) {return NetworkCapabilities.TRANSPORT_LOWPAN;} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_USB)) {return NetworkCapabilities.TRANSPORT_USB;}}return -1;}
}
Android10之后,请使用新的API方法, 工具类可以根据业务需求去扩展, 供参考。
相关文章:
Android 获取网络连接状态新方法
一. 问题背景 Android12上,有的app模块判断当前网络的类型和连接状态时,还是使用的旧的API,导致返回的结果不准确,影响代码逻辑判断,本篇文章就这一问题,整理一下判断网络类型和连接状态的新方法。 二. 原因…...
可缝合神经网络
文章目录 Stitchable Neural Networks摘要本文方法实验结果 Stitchable Neural Networks 摘要 包含大量强大的预训练模型族(如ResNet/DeiT)的model zoo已经达到了前所未有的范围,这对深度学习的成功有重要贡献。由于每个模型族都由具有不同尺度的预训练模型(例如&…...
Android优化篇|网络预连接
作者:苍耳叔叔 一个示例 前后分别去请求同一个域名下的接口,通过 Charles 抓包,可以看到 Timing 下面的时间: 第二次请求时,DNS、Connect 和 TLS Handshake 部分都是 -,说明没有这部分的耗时,…...
pyspark使用XGboost训练模型实例
遇到一个还不错的使用Xgboost训练模型的githubhttps://github.com/MachineLP/Spark-/tree/master/pyspark-xgboost 1、这是一个跑通的代码实例,使用的是泰坦尼克生还数据,分类模型。 这里使用了Pipeline来封装特征处理和模型训练步骤,保存为…...
完整模型的训练套路
从心所欲 不逾矩 天大地大 皆可去 一、官方模型的初使用 使用VGG16模型 VGG模型使用代码示例: import torchvision.models from torch import nndataset torchvision.datasets.CIFAR10(/cifar10, False, transformtorchvision.transforms.ToTensor())vgg16_true …...
PtahDAO:全球首个DAO治理资产信托计划的金融平台
金融科技是当今世界最具创新力和影响力的领域之一,区块链技术作为金融科技的核心驱动力,正在颠覆传统的金融模式,为全球用户提供更加普惠、便捷、安全的金融服务。在这个变革的浪潮中,PtahDAO(普塔道)作为全…...
从零搭建一个react + electron项目
最近打算搭建一个react electron的项目,发现并不是那么傻瓜式 于是记录一下自己的实践步骤 通过create-react-app 创建react项目 npx create-react-app my-app 安装electron依赖 npm i electron -D暴露react项目的配置文件(这一步看自己需求,…...
MATLAB /Simulink 快速开发STM32(使用st官方工具 STM32-MAT/TARGET),以及开发过程
配置好环境以后就是开发: stm32cube配置芯片,打开matlab添加ioc文件,写处理逻辑,生成代码,下载到板子中去。 配置需要注意事项: STM32CUBEMAX6.5.0 MABLAB2022BkeilV5.2 Matlab生成的代码CTRLB 其中关键的…...
LeetCode 热题 100 JavaScript--102. 二叉树的层序遍历
给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 输入:root [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]] 示例 2: 输入:root [1…...
常见Git命令
Git常见命令 1. 添加单个文件 git add a.txt2. 添加多个文件 git add a.txt b.txt c.txt3. 添加(commit)修改,此时修改还未push到服务器上 git commit -m "修改了a.txt内容"4. 提交(push)修改,此时修改会同步到服务器上 git push5. 查看当…...
在C语言中调用汇编语言的函数
在C语言中调用汇编文件中的函数,要做的主要工作有两个: 一是在C语言中声明函数原型,并加extern关键字; 二是在汇编中用EXPORT导出函数名,并用该函数名作为汇编代码段的标识,最后用mov pc, lr返回。然后&a…...
Delphi Professional Crack,IDE插件开发和扩展IDE
Delphi Professional Crack,IDE插件开发和扩展IDE 构建具有强大视觉设计功能的单源多平台本机应用程序。 Delphi帮助您使用Object Pascal为Windows、Mac、Mobile、IoT和Linux构建和更新数据丰富、超连接、可视化的应用程序。Delphi Professional适合个人开发人员和小型团队构建…...
程序框架-公共MONO模块
作用:让没有继承MONO的类可以开启协程,可以update更新,可以统一管理update MonoController脚本继承MonoBehaviour使得脚本过场不移除,并通过UnityAction可以添加多个函数(多播委托),实现Update…...
采用鲁棒随机森林实现的流异常检测:Python应用的一种新型机器学习方法
在数字化和互联网化日益普遍的现代社会,处理海量的网络流量数据是网络安全分析中不可或缺的一部分。流异常检测是一种重要的技术,用于发现可能的安全威胁,例如:网络攻击、恶意行为和系统故障等。随机森林是一种普遍用于解决这类问题的机器学习算法。在本文中,我们将介绍一…...
缓存友好在实际编程中的重要性
引入 当CPU执行程序时,需要频繁地访问主存储器(RAM)中的数据和指令。然而,主存储器的访问速度相对较慢,与CPU的运算速度相比存在显著差异,每次都从主存中读取数据都会导致相对较长的等待时间,从…...
uni-ajax网络请求库使用
uni-ajax网络请求库使用 uni-ajax是什么 uni-ajax是基于 Promise 的轻量级 uni-app 网络请求库,具有开箱即用、轻量高效、灵活开发 特点。 下面是安装和使用教程 安装该请求库到项目中 npm install uni-ajax编辑工具类request.js // ajax.js// 引入 uni-ajax 模块 import ajax…...
MYSQL进阶-事务
1.什么是数据库事务? 事务是一个不可分割的数据库操作序列,也是数据库并发控制的基本单位,其执 行的结果必须使数据库从一种一致性状态变到另一种一致性状态。事务是逻辑上 的一组操作,要么都执行,要么都不执行。 事务…...
python 常见数据类型和方法
不可变数据类型 不支持直接增删改 只能查 str 字符串 int 整型 bool 布尔值 None None型特殊常量 tuple 元组(,,,)回到顶部 可变数据类型,支持增删改查 list 列表[,,,] dic 字典{"":"","": ,} set 集合("",""…...
a-date-picker报错TypeError: date4.locale is not a function
问题描述 使用日期选择器,数据从后端获得,再赋值给a-date-picker做数据回显,遇到这个报错,排错后定位到a-date-picker组件本身接收数据的问题。 如果使用了dayjs或moment库来处理时间字符串,并且使用.format对时间数据…...
LNMP安装
目录 1、LNMP简述: 1.1、概述 1.2、LNMP是一个缩写词,及每个字母的含义 1.3、编译安装与yum安装差异 1.4、编译安装的优点 2、通过LNMP创建论坛 2.1、 安装nginx服务 2.1.1、关闭防火墙 2.1.2、创建运行用户 2.1.3、 编译安装 2.1.4、 优化路…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
