当前位置: 首页 > 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 = "未知网络"}}
}

相关文章:

  • POST参数里加号+变成空格的问题处理
  • C++内存管理【new 和 delete 关键字】笔记
  • 【Leetcode】938. 二叉搜索树的范围和
  • 【QT+QGIS跨平台编译】之五十五:【QGIS_CORE跨平台编译】—【qgsmeshcalcparser.cpp生成】
  • 【C#】SixLabors.ImageSharp和System.Drawing两者知多少
  • 刷题 16 前缀和
  • 常用网络协议的学习
  • 项目实战:Qt监测操作系统物理网卡通断v1.1.0(支持windows、linux、国产麒麟系统)
  • YOLOv9图像标注和格式转换
  • 通过配置数据库事件(Event)来实现定时导出 MySQL 数据库
  • XSS简介及xsslabs第一关
  • Linux 学习笔记(1-3)
  • 【Spring】回顾反射机制
  • 2324. 生活的艰辛(网络流,最小割,最大密度子图)#困难,重点难点
  • 软件License授权原理
  • [LeetCode] Wiggle Sort
  • [译]Python中的类属性与实例属性的区别
  • ECS应用管理最佳实践
  • ES学习笔记(10)--ES6中的函数和数组补漏
  • golang中接口赋值与方法集
  • Linux链接文件
  • node学习系列之简单文件上传
  • React as a UI Runtime(五、列表)
  • React的组件模式
  • storm drpc实例
  • Swoft 源码剖析 - 代码自动更新机制
  • webpack+react项目初体验——记录我的webpack环境配置
  • 动态魔术使用DBMS_SQL
  • 盘点那些不知名却常用的 Git 操作
  • 前端js -- this指向总结。
  • 前嗅ForeSpider中数据浏览界面介绍
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 实习面试笔记
  • 使用docker-compose进行多节点部署
  • 事件委托的小应用
  • 微信小程序开发问题汇总
  • 想写好前端,先练好内功
  • 学习Vue.js的五个小例子
  • 怎么把视频里的音乐提取出来
  • 昨天1024程序员节,我故意写了个死循环~
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​Linux·i2c驱动架构​
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (16)Reactor的测试——响应式Spring的道法术器
  • (26)4.7 字符函数和字符串函数
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转) ns2/nam与nam实现相关的文件
  • (转)linux下的时间函数使用
  • (转)母版页和相对路径
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • .bat批处理(九):替换带有等号=的字符串的子串
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .NET CF命令行调试器MDbg入门(四) Attaching to Processes