当前位置: 首页 > news >正文

Android 监听网络状态变化

文章目录

  • Android 监听网络状态变化
    • 封装工具类
    • 使用

Android 监听网络状态变化

封装工具类

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
/*** 网络工具类*/
object NetworkUtils {// 无网络const val NETWORK_NONE = -1// wificonst val NETWORK_WIFI = 1// 3Gconst val NETWORK_2G = 2//3Gconst val NETWORK_3G = 3// 4Gconst val NETWORK_4G = 4// 5Gconst val NETWORK_5G = 5// 未知网络const val NETWORK_UNKNOWN = 6/***  获取网络类型*/@JvmStatic@RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)fun getNetWorkType(context: Context): Int {val connectivityManager =context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerval info = connectivityManager.activeNetworkInfo // 获取当前网络状态if (info != null && info.isAvailable) {when (info.type) {ConnectivityManager.TYPE_WIFI -> {return NETWORK_WIFI}ConnectivityManager.TYPE_MOBILE -> {when (info.subtype) {TelephonyManager.NETWORK_TYPE_GSM,TelephonyManager.NETWORK_TYPE_GPRS,TelephonyManager.NETWORK_TYPE_CDMA,TelephonyManager.NETWORK_TYPE_EDGE,TelephonyManager.NETWORK_TYPE_1xRTT,TelephonyManager.NETWORK_TYPE_IDEN ->return NETWORK_2GTelephonyManager.NETWORK_TYPE_TD_SCDMA,TelephonyManager.NETWORK_TYPE_EVDO_A,TelephonyManager.NETWORK_TYPE_UMTS,TelephonyManager.NETWORK_TYPE_EVDO_0,TelephonyManager.NETWORK_TYPE_HSDPA,TelephonyManager.NETWORK_TYPE_HSUPA,TelephonyManager.NETWORK_TYPE_HSPA,TelephonyManager.NETWORK_TYPE_EVDO_B,TelephonyManager.NETWORK_TYPE_EHRPD,TelephonyManager.NETWORK_TYPE_HSPAP ->return NETWORK_3GTelephonyManager.NETWORK_TYPE_IWLAN,TelephonyManager.NETWORK_TYPE_LTE ->return NETWORK_4GTelephonyManager.NETWORK_TYPE_NR ->return NETWORK_5Gelse -> {val subtypeName = info.subtypeNamereturn if (subtypeName.equals("TD-SCDMA", ignoreCase = true)|| subtypeName.equals("WCDMA", ignoreCase = true)|| subtypeName.equals("CDMA2000", ignoreCase = true)) {NETWORK_3G} else {NETWORK_UNKNOWN}}}}else -> {return NETWORK_UNKNOWN}}} else {return NETWORK_NONE}}/*** 获取网络类型名*/@JvmStaticfun getNetWorkTypeName(context: Context): String {return when (getNetWorkType(context)) {NETWORK_WIFI -> "NETWORK_WIFI"NETWORK_5G -> "NETWORK_5G"NETWORK_4G -> "NETWORK_4G"NETWORK_3G -> "NETWORK_3G"NETWORK_2G -> "NETWORK_2G"NETWORK_NONE -> "NETWORK_NONE"else -> "NETWORK_UNKNOWN"}}/*** 判断网络连接是否可用*/@JvmStaticfun isNetworkAvailable(context: Context): Boolean {val connectivityManager =context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager//如果仅仅是用来判断网络连接//则可以使用 cm.getActiveNetworkInfo().isAvailable();val info = connectivityManager.allNetworkInfofor (i in info.indices) {if (info[i].state == NetworkInfo.State.CONNECTED) {return true}}return false}/*** 判断网络是否可用* 需添加权限*/@JvmStatic@RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)fun isAvailable(context: Context): Boolean {val info = getActiveNetworkInfo(context)return info != null && info.isAvailable}/*** 判断网络是否连接* 需添加权限*/@JvmStatic@RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)fun isConnected(context: Context): Boolean {val info = getActiveNetworkInfo(context)return info != null && info.isConnected}/*** 判断是否有外网连接(普通方法不能判断外网的网络是否连接,比如连接上局域网)* 不要在主线程使用,会阻塞线程*/@JvmStaticfun ping(): Boolean {var result: String? = nulltry {val ip = "www.baidu.com" // ping 的地址,可以换成任何一种可靠的外网val p = Runtime.getRuntime().exec("ping -c 3 -w 100 $ip") // ping网址3次// 读取ping的内容,可以不加val input = p.inputStreamval `in` = BufferedReader(InputStreamReader(input))val stringBuffer = StringBuffer()var content: String? = ""while (`in`.readLine().also { content = it } != null) {stringBuffer.append(content)}Log.e("TAG", "result content : $stringBuffer");// ping的状态val status = p.waitFor()if (status == 0) {result = "success"return true} else {result = "failed"}} catch (e: IOException) {result = "IOException"} catch (e: InterruptedException) {result = "InterruptedException"} finally {Log.e("TAG", "result = $result");}return false}/*** ping IP* 不要在主线程使用,会阻塞线程*/@JvmStaticfun ping(ip: String): Boolean {var result: String? = nulltry {// ping网址3次val p = Runtime.getRuntime().exec("ping -c 3 -w 100 $ip")// 读取ping的内容,可以不加val input = p.inputStreamval `in` = BufferedReader(InputStreamReader(input))val stringBuffer = StringBuffer()var content: String? = ""while (`in`.readLine().also { content = it } != null) {stringBuffer.append(content)}Log.e("TAG", "result content : $stringBuffer");// ping的状态val status = p.waitFor()if (status == 0) {result = "success"return true} else {result = "failed"}} catch (e: IOException) {result = "IOException"} catch (e: InterruptedException) {result = "InterruptedException"} finally {Log.e("TAG", "result = $result");}return false}/*** 判断WIFI是否打开*/@JvmStatic@RequiresPermission(Manifest.permission.ACCESS_WIFI_STATE)fun isWifiEnabled(context: Context): Boolean {val wifiManager =context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManagerreturn wifiManager.isWifiEnabled}/*** 判断网络连接方式是否为WIFI*/@JvmStaticfun isWifi(context: Context): Boolean {val networkINfo = getActiveNetworkInfo(context)return networkINfo != null && networkINfo.type == ConnectivityManager.TYPE_WIFI}/*** 判断wifi是否连接状态*/@JvmStatic@RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)fun isWifiConnected(context: Context): Boolean {val connectivityManager =context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerreturn connectivityManager.activeNetworkInfo != null && connectivityManager.activeNetworkInfo!!.type == ConnectivityManager.TYPE_WIFI}/*** 判断网络是否是4G*/@JvmStatic@RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)fun is4G(context: Context): Boolean {val info = getActiveNetworkInfo(context)return info != null && info.isAvailable && info.subtype == TelephonyManager.NETWORK_TYPE_LTE}/*** 判断网络是否是5G*/@JvmStatic@RequiresPermission(Manifest.permission.ACCESS_NETWORK_STATE)fun is5G(context: Context): Boolean {val info = getActiveNetworkInfo(context)return (info != null && info.isAvailable && info.subtype == TelephonyManager.NETWORK_TYPE_NR)}/*** 判断GPS是否打开*/@JvmStaticfun isGpsEnabled(context: Context): Boolean {val locationManager = context.getSystemService(Context.LOCATION_SERVICE) as LocationManagerval accessibleProviders = locationManager.getProviders(true)return accessibleProviders.size > 0}/*** 打开网络设置界面*/@JvmStaticfun openWirelessSettings(context: Context) {
//        context.startActivity(Intent(Settings.ACTION_SETTINGS)) // 跳转设置界面context.startActivity(Intent(Settings.ACTION_WIFI_SETTINGS)) //跳转wifi设置界面}/*** 获取活动网络信息*/private fun getActiveNetworkInfo(context: Context): NetworkInfo? {val connectivityManager =context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManagerreturn connectivityManager.activeNetworkInfo}/*** 获取移动网络运营商名称** 如中国联通、中国移动、中国电信** @param context 上下文* @return 移动网络运营商名称*/@JvmStaticfun getNetworkOperatorName(context: Context): String? {val telephonyManager =context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManagerreturn telephonyManager.networkOperatorName}/*** 获取移动终端类型** @param context 上下文* @return 手机制式**  * [TelephonyManager.PHONE_TYPE_NONE] : 0 手机制式未知*  * [TelephonyManager.PHONE_TYPE_GSM] : 1 手机制式为GSM,移动和联通*  * [TelephonyManager.PHONE_TYPE_CDMA] : 2 手机制式为CDMA,电信*  * [TelephonyManager.PHONE_TYPE_SIP] : 3**/@JvmStaticfun getPhoneType(context: Context): Int {val telephonyManager =context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManagerreturn telephonyManager.phoneType}
}
/**** 网络工具帮助类*/
object NetworkHelper {private var currentNetworkType: Int = -1private val mListeners = hashSetOf<OnNetworkStateChangedListener>()fun registerListener(context: Context, listener: OnNetworkStateChangedListener) {val preSize = mListeners.sizemListeners.add(listener)// 防止重复注册if (preSize == 0 && mListeners.size == 1) {val mFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)context.registerReceiver(NetworkStateChangedReceiver, mFilter)}}fun isRegistered(listener: OnNetworkStateChangedListener): Boolean {return mListeners.contains(listener)}fun unregisterListener(context: Context, listener: OnNetworkStateChangedListener) {val preSize = mListeners.sizemListeners.remove(listener)// 防止重复注销if (preSize == 1 && mListeners.size == 0) {context.unregisterReceiver(NetworkStateChangedReceiver)}}/*** 网络状态改变广播*/object NetworkStateChangedReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {if (ConnectivityManager.CONNECTIVITY_ACTION == intent.action) {val netWorkType = NetworkUtils.getNetWorkType(context)if (currentNetworkType == netWorkType) {return}currentNetworkType = netWorkTypeif (netWorkType == NetworkUtils.NETWORK_NONE) {for (listener in mListeners) {listener.onDisconnected()}} else {for (listener in mListeners) {listener.onConnected(currentNetworkType)}}}}}interface OnNetworkStateChangedListener {fun onDisconnected()fun onConnected(networkType: Int)}
}

使用

// 注册监听
NetworkHelper.registerListener(mContext, this)// 注销监听NetworkHelper.unregisterListener(mContext, this)
override fun onDisconnected() {Log.e(NETWORK, "当前无网络连接")tvNetwork.text = "当前无网络连接"
}override fun onConnected(networkType: Int) {when (networkType) {NetworkUtils.NETWORK_WIFI -> {Log.e(NETWORK, "切换到wifi环境下")tvNetwork.text = "切换到wifi环境下"}NetworkUtils.NETWORK_2G -> {Log.e(NETWORK, "切换到2G环境下")tvNetwork.text = "切换到2G环境下"}NetworkUtils.NETWORK_3G -> {Log.e(NETWORK, "切换到3G环境下")tvNetwork.text = "切换到3G环境下"}NetworkUtils.NETWORK_4G -> {Log.e(NETWORK, "切换到4G环境下")tvNetwork.text = "切换到4G环境下"}NetworkUtils.NETWORK_5G -> {Log.e(NETWORK, "切换到5G环境下")tvNetwork.text = "切换到5G环境下"}NetworkUtils.NETWORK_UNKNOWN -> {Log.e(NETWORK, "未知网络")tvNetwork.text = "未知网络"}}
}

相关文章:

Android 监听网络状态变化

文章目录 Android 监听网络状态变化封装工具类使用 Android 监听网络状态变化 封装工具类 <uses-permission android:name"android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name"android.permission.ACCESS_WIFI_STATE"…...

【LeetCode】一周中的第几天+ 一年中的第几天

2023-12-30 文章目录 一周中的第几天方法一&#xff1a;模拟思路步骤 方法二&#xff1a;调用库函数方法三&#xff1a;调用库函数 [1154. 一年中的第几天](https://leetcode.cn/problems/day-of-the-year/)方法一&#xff1a;直接计算思路&#xff1a; 方法二&#xff1a;调用…...

深度学习 精选笔记(10)简单案例:房价预测

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…...

DBGridEh 的排序

DBGridEh 可以点列抬头使得记录按该列排序 不需要写代码&#xff0c;只需要设置好&#xff0c;它就能排序。 网上的文章一般写了如何设置。但一般都少说了一条。 先说如何设置&#xff1a; 1. OptionsEh.AutoSortMarking 设置为 True&#xff0c;如果是设计期属性面板&…...

spring-boot-starter-parent和spring-boot-dependencies介绍

springboot项目的pom文件中&#xff0c;我们经常看见这样(下图)两种springboot的版本依赖管理方式&#xff1b;图片中的这两种依赖声明方式任意用其中一种都可以。文章后面会简单阐述一下区别和使用场景。 事例中完整的pom文件 <?xml version"1.0" encoding&quo…...

缓存穿透解决方案之布隆过滤器

布隆过滤器可以快速判断数据是否存在&#xff0c;避免从数据库中查询数据是否存在&#xff0c;减轻数据库的压力 布隆过滤器是由一个初值为0的bit数组和N个哈希函数&#xff0c;可以用来快速的判断某个数据是否存在 当我们想要标记某个数据是否存在时&#xff0c;布隆过滤器会…...

pptx和ppt有什么区别?了解两者之间的微妙差异

在现代办公和学习环境中&#xff0c;PowerPoint已成为我们生活中不可或缺的一部分。随着技术的不断进步&#xff0c;PowerPoint的格式也在不断更新。对于许多初学者&#xff0c;可能会对PPT和PPTX这两种格式感到困惑。本文旨在深入探讨PPTX与PPT之间的主要差异&#xff0c;帮助…...

LabVIEW水下温盐深数据一体化采集与分析

LabVIEW水下温盐深数据一体化采集与分析 开发一个基于LabVIEW的水下温盐深数据一体化采集与分析系统&#xff0c;实现海洋环境监测的自动化和精确化。通过集成温度、盐度和深度传感器&#xff0c;结合USB数据采集卡&#xff0c;利用LabVIEW软件开发的图形化界面&#xff0c;实…...

适配器模式 详解 设计模式

适配器模式 适配器模式是一种结构型设计模式&#xff0c;其主要作用是解决两个不兼容接口之间的兼容性问题。适配器模式通过引入一个适配器来将一个类的接口转换成客户端所期望的另一个接口&#xff0c;从而让原本由于接口不匹配而无法协同工作的类能够协同工作。 结构 适配…...

探索rsync远程同步和SSH免密登录的奥秘

目录 集群分发脚本xsyncscp&#xff08;secure copy&#xff09;安全拷贝rsync 远程同步工具集群分发脚本 SSH免密登录免密登录原理SSH免密登录配置生成公钥和私钥授权测试 在现代科技飞速发展的时代&#xff0c;数据的备份和迁移成为了一个重要的课题。其中&#xff0c;rsync远…...

JavaScript new、apply call 方法

new、apply、call、bind JavaScript 中的 apply、call和 bind 方法是前端代码开发中相当重要的概念&#xff0c;并且与 this 的指向密切相关 new new 关键词的主要作用 就是执行一个构造函数、返回一个实例对象 根据构造函数的情况&#xff0c;来确定是否可以接受参数的传递…...

助力智能化农田作物除草,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建农田作物场景下玉米苗、杂草检测识别分析系统

在我们前面的系列博文中&#xff0c;关于田间作物场景下的作物、杂草检测已经有过相关的开发实践了&#xff0c;结合智能化的设备可以实现只能除草等操作&#xff0c;玉米作物场景下的杂草检测我们则少有涉及&#xff0c;这里本文的主要目的就是想要基于DETR模型来开发构建玉米…...

O(1)转移线性dpLeetCode 2369. 检查数组是否存在有效划分

一、题目 1、题目描述 给你一个下标从 0 开始的整数数组 nums &#xff0c;你必须将数组划分为一个或多个 连续 子数组。 如果获得的这些子数组中每个都能满足下述条件 之一 &#xff0c;则可以称其为数组的一种 有效 划分&#xff1a; 子数组 恰 由 2 个相等元素组成&#xf…...

【力扣hot100】刷题笔记Day17

前言 今天竟然不用开组会&#xff01;天大的好消息&#xff0c;安心刷题了 46. 全排列 - 力扣&#xff08;LeetCode&#xff09; 回溯&#xff08;排列&#xff09; class Solution:def permute(self, nums: List[int]) -> List[List[int]]:# 回溯def backtrack():if len(…...

leetcode日记(34)通配符匹配

这道题做了很久很久……一开始我想用的方法是使用双指针&#xff0c;分别指向两数组&#xff0c;然后依次按照题目中的规则遍历&#xff0c;做了很久发现时间超限了&#xff01;这是我最后超时的代码&#xff01; class Solution { public:bool isMatch(string s, string p) {…...

一张图读懂人工智能

一、生成人工智能的概念和应用&#xff0c;以及如何使用大型语言模型进行聊天和创造原创内容。这项技术将会对人类和企业产生深远影响。 计算机获得学习、思考和交流的能力&#xff0c;被称为生成人工智能。生成人工智能可以立即获得人类所有知识的总和&#xff0c;并回答任何…...

5.37 BCC工具之uflow.py解读

一,工具简介 uflow工具用于跟踪方法的进入和退出事件,并打印一个可视化的流程图,显示方法是如何进入和退出的,类似于带有断点的跟踪调试器。这对于理解Java、Perl、PHP、Python、Ruby和Tcl等高级语言中的程序流非常有用,这些语言为方法调用提供了USDT探测。 二,代码示例…...

R语言简介,R语言开发环境搭建步骤,R基础语法以及注释详解

R语言是一种用于统计计算与绘图的编程语言&#xff0c;由新西兰奥克兰大学的统计学家罗斯伊哈卡和罗伯特杰特曼于1993年发明。R语言是一种自由、免费、源代码开放的软件&#xff0c;属于GNU系统的一个分支&#xff0c;如今被广泛地应用于统计分析、数据挖掘等领域。 R语言的特…...

【Django】执行查询—检索对象

检索对象 以下述模型为基础&#xff0c;讨论检索对象的方式方法&#xff1a; from datetime import datefrom django.db import modelsclass Blog(models.Model):name models.CharField(max_length100)tagline models.TextField()def __str__(self):return self.nameclass …...

Python:练习:编写一个程序,写入一个美金数量,然后显示出如何用最少的20美元、10美元、5美元和1美元来付款

案例&#xff1a; python编写一个程序&#xff0c;写入一个美金数量&#xff0c;然后显示出如何用最少的20美元、10美元、5美元和1美元来付款&#xff1a; Enter a dollar amout:93 $20 bills: 4 $10 bills: 1 $5 bills:0 $1 bills:3 思考&#xff1a; 写入一个美金数量&…...

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…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

如何更改默认 Crontab 编辑器 ?

在 Linux 领域中&#xff0c;crontab 是您可能经常遇到的一个术语。这个实用程序在类 unix 操作系统上可用&#xff0c;用于调度在预定义时间和间隔自动执行的任务。这对管理员和高级用户非常有益&#xff0c;允许他们自动执行各种系统任务。 编辑 Crontab 文件通常使用文本编…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)

前言&#xff1a; 双亲委派机制对于面试这块来说非常重要&#xff0c;在实际开发中也是经常遇见需要打破双亲委派的需求&#xff0c;今天我们一起来探索一下什么是双亲委派机制&#xff0c;在此之前我们先介绍一下类的加载器。 目录 ​编辑 前言&#xff1a; 类加载器 1. …...

从面试角度回答Android中ContentProvider启动原理

Android中ContentProvider原理的面试角度解析&#xff0c;分为​​已启动​​和​​未启动​​两种场景&#xff1a; 一、ContentProvider已启动的情况 1. ​​核心流程​​ ​​触发条件​​&#xff1a;当其他组件&#xff08;如Activity、Service&#xff09;通过ContentR…...

xmind转换为markdown

文章目录 解锁思维导图新姿势&#xff1a;将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件&#xff08;ZIP处理&#xff09;2.解析JSON数据结构3&#xff1a;递归转换树形结构4&#xff1a;Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...