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

Android 状态栏WiFi图标的显示逻辑

1. 状态栏信号图标


1.1 WIFI信号显示


WIFI信号在状态栏的显示如下图所示

当WiFi状态为关闭时,状态栏不会有任何显示。当WiFi状态打开时,会如上图所示,左侧表示有可用WiFi,右侧表示当前WiFi打开但未连接。

当WiFi状态连接时,会如上图所示,显示信号连接强度和数据连接状态。

1.2 图标更新流程框架


如图所示,WiFi图标的显示流程主要是通过监听系统的WiFi状态,然后通知UI去实时的刷新图标资源。NetworkControllerImpl.java 继承 BroadcastReceiver 监听系统WiFi状态的变化。

2. WIFI图标更新流介绍

2.1 重要类

frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\connectivity\NetworkControllerImpl.java
定义相关函数,继承BroadcastReceiver监听系统广播,动态注册广播接收器。是状态栏WiFi图标更新的核心类。
frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\connectivity\WifiIcons.java
定义了 Wifi 信号更新所需的图标资源。
frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java

frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\connectivity\WifiSignalController.java

2.2 WIFI图标更新流程


(1)WifiNetworkController实例化,在NetworkControllerImpl.java进行实例化

frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\connectivity\NetworkControllerImpl.java

    @VisibleForTestingNetworkControllerImpl(Context context, ConnectivityManager connectivityManager,TelephonyManager telephonyManager,TelephonyListenerManager telephonyListenerManager,WifiManager wifiManager,SubscriptionManager subManager,Config config,Looper bgLooper,Executor bgExecutor,CallbackHandler callbackHandler,AccessPointControllerImpl accessPointController,StatusBarPipelineFlags statusBarPipelineFlags,DataUsageController dataUsageController,SubscriptionDefaults defaultsHandler,DeviceProvisionedController deviceProvisionedController,BroadcastDispatcher broadcastDispatcher,UserTracker userTracker,DemoModeController demoModeController,CarrierConfigTracker carrierConfigTracker,WifiStatusTrackerFactory trackerFactory,MobileSignalControllerFactory mobileFactory,@Main Handler handler,DumpManager dumpManager,LogBuffer logBuffer) {mContext = context;mTelephonyListenerManager = telephonyListenerManager;mConfig = config;mMainHandler = handler;mReceiverHandler = new Handler(bgLooper);mBgLooper = bgLooper;mBgExecutor = bgExecutor;mCallbackHandler = callbackHandler;mStatusBarPipelineFlags = statusBarPipelineFlags;mDataSaverController = new DataSaverControllerImpl(context);mBroadcastDispatcher = broadcastDispatcher;mMobileFactory = mobileFactory;mSubscriptionManager = subManager;mSubDefaults = defaultsHandler;mConnectivityManager = connectivityManager;mHasMobileDataFeature = telephonyManager.isDataCapable();mDemoModeController = demoModeController;mCarrierConfigTracker = carrierConfigTracker;mDumpManager = dumpManager;mLogBuffer = logBuffer;// telephonymPhone = telephonyManager;// wifimWifiManager = wifiManager;mLocale = mContext.getResources().getConfiguration().locale;mAccessPoints = accessPointController;mDataUsageController = dataUsageController;mDataUsageController.setNetworkController(this);// TODO: Find a way to move this into DataUsageController.mDataUsageController.setCallback(new DataUsageController.Callback() {@Overridepublic void onMobileDataEnabled(boolean enabled) {mCallbackHandler.setMobileDataEnabled(enabled);notifyControllersMobileDataChanged();}});mWifiSignalController = new WifiSignalController(mContext, mHasMobileDataFeature,mCallbackHandler, this, mWifiManager, trackerFactory,mReceiverHandler);

注册广播

@VisibleForTestingvoid registerListeners() {for (int i = 0; i < mMobileSignalControllers.size(); i++) {MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i);mobileSignalController.registerListener();}if (mSubscriptionListener == null) {mSubscriptionListener = new SubListener(mBgLooper);}mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);// broadcastsIntentFilter filter = new IntentFilter();filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);filter.addAction(Intent.ACTION_SERVICE_STATE);filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);filter.addAction(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);filter.addAction(TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);filter.addAction(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED);filter.addAction(TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED);filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mReceiverHandler);mListening = true;// Initial setup of connectivity. Handled as if we had received a sticky broadcast of// ConnectivityManager.CONNECTIVITY_ACTION.mReceiverHandler.post(this::updateConnectivity);// Initial setup of WifiSignalController. Handled as if we had received a sticky broadcast// of WifiManager.WIFI_STATE_CHANGED_ACTION or WifiManager.NETWORK_STATE_CHANGED_ACTIONmReceiverHandler.post(mWifiSignalController::fetchInitialState);// Initial setup of mLastServiceState. Only run if there is no service state yet.// Each MobileSignalController will also get their correspondingmReceiverHandler.post(() -> {if (mLastServiceState == null) {mLastServiceState = mPhone.getServiceState();if (mMobileSignalControllers.size() == 0) {recalculateEmergency();}}});updateMobileControllers();// Initial setup of emergency information. Handled as if we had received a sticky broadcast// of TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED.mReceiverHandler.post(this::recalculateEmergency);}

当收到广播时,更新图标

@Overridepublic void onReceive(Context context, Intent intent) {if (true) {Log.d(TAG, "onReceive: intent=" + intent);}final String action = intent.getAction();mLogBuffer.log(TAG,LogLevel.INFO,logMessage -> {logMessage.setStr1(action);return Unit.INSTANCE;},logMessage -> String.format(Locale.US,"Received broadcast with action \"%s\"",logMessage.getStr1()));switch (action) {case ConnectivityManager.CONNECTIVITY_ACTION:updateConnectivity();break;case Intent.ACTION_AIRPLANE_MODE_CHANGED:refreshLocale();updateAirplaneMode(false);break;case TelephonyManager.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED:// We are using different subs now, we might be able to make calls.recalculateEmergency();break;case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:// Notify every MobileSignalController so they can know whether they are the// data sim or not.for (int i = 0; i < mMobileSignalControllers.size(); i++) {MobileSignalController controller = mMobileSignalControllers.valueAt(i);controller.handleBroadcast(intent);}mConfig = Config.readConfig(mContext);mReceiverHandler.post(this::handleConfigurationChanged);break;case TelephonyManager.ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED: {// Notify the relevant MobileSignalController of the changeint subId = intent.getIntExtra(TelephonyManager.EXTRA_SUBSCRIPTION_ID,INVALID_SUBSCRIPTION_ID);if (SubscriptionManager.isValidSubscriptionId(subId)) {if (mMobileSignalControllers.indexOfKey(subId) >= 0) {mMobileSignalControllers.get(subId).handleBroadcast(intent);}}}break;case Intent.ACTION_SIM_STATE_CHANGED:// Avoid rebroadcast because SysUI is direct boot aware.if (intent.getBooleanExtra(Intent.EXTRA_REBROADCAST_ON_UNLOCK, false)) {break;}// Might have different subscriptions now.updateMobileControllers();break;case Intent.ACTION_SERVICE_STATE:mLastServiceState = ServiceState.newFromBundle(intent.getExtras());if (mMobileSignalControllers.size() == 0) {// If none of the subscriptions are active, we might need to recalculate// emergency state.recalculateEmergency();}break;case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:mConfig = Config.readConfig(mContext);mReceiverHandler.post(this::handleConfigurationChanged);break;case Settings.Panel.ACTION_INTERNET_CONNECTIVITY:mMainHandler.post(() -> mInternetDialogFactory.create(true,mAccessPoints.canConfigMobileData(), mAccessPoints.canConfigWifi(),null /* view */));break;default:int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,INVALID_SUBSCRIPTION_ID);if (SubscriptionManager.isValidSubscriptionId(subId)) {if (mMobileSignalControllers.indexOfKey(subId) >= 0) {mMobileSignalControllers.get(subId).handleBroadcast(intent);} else {// Can't find this subscription...  We must be out of date.updateMobileControllers();}} else {// No sub id, must be for the wifi.mWifiSignalController.handleBroadcast(intent);}break;}}

相关文章:

Android 状态栏WiFi图标的显示逻辑

1. 状态栏信号图标 1.1 WIFI信号显示 WIFI信号在状态栏的显示如下图所示 当WiFi状态为关闭时&#xff0c;状态栏不会有任何显示。当WiFi状态打开时&#xff0c;会如上图所示&#xff0c;左侧表示有可用WiFi&#xff0c;右侧表示当前WiFi打开但未连接。 当WiFi状态连接时&#x…...

更改 DeepXDE 的后端

DeepXDE 库为科学计算和工程优化等领域提供了深度学习方法&#xff0c;是一个非常有用的工具。其中一个重要的功能是它允许用户自定义后端。在本文中&#xff0c;我们将指导如何更改 DeepXDE 的后端&#xff0c;并且验证更改是否成功。 更改 DeepXDE 的后端 DeepXDE 支持多种…...

SpringBoot之Zuul服务

概述 Spring Cloud Netflix zuul组件是微服务架构中的网关组件,Zuul作为统一网关,是所有访问该平台的请求入口,核心功能是路由和过滤。 目前公司业务就是基于Zuul搭建的网关服务,且提供的服务包括转发请求(路由)、黑名单IP访问拦截、URL资源访问时的权限拦截、统一访问日志记…...

Go-变量

可以理解为一个昵称 以后这个昵称就代指这些信息 var sg string "czy" 声明赋值 package mainimport "fmt"func main() {var sg string "陈政洋"fmt.Println(sg)var age int 73fmt.Println(age)var flag bool truefmt.Println(flag) } …...

【CTF-Crypto】RSA-选择明密文攻击 一文通

RSA&#xff1a;选择明密文攻击 关于选择明/密文攻击&#xff0c;其实这一般是打一套组合拳的&#xff0c;在网上找到了利用的思路&#xff0c;感觉下面这个题目是真正将这个问题实现了&#xff0c;所以还是非常棒的一道题&#xff0c;下面先了解一下该知识点&#xff1a;(来自…...

Pytorch基础:torch.expand() 和 torch.repeat()

在torch中&#xff0c;如果要改变某一个tensor的维度&#xff0c;可以利用view、expand、repeat、transpose和permute等方法&#xff0c;这里对这些方法的一些容易混淆的地方做个总结。 expand和repeat函数是pytorch中常用于进行张量数据复制和维度扩展的函数&#xff0c;但其…...

如何正确安装Scrapy 2.6.1并解决常见的Python环境问题

在配置Python环境和安装包时&#xff0c;常常会遇到版本冲突和路径问题&#xff0c;特别是当系统中存在多个Python版本时。本文将指导你如何在CentOS系统中正确使用pip3安装Scrapy 2.6.1&#xff0c;并解决一些常见的环境问题。 步骤1: 确认和升级 pip3 确认 pip3 的版本&…...

阵痛中的乳业产业,何时才能成为下一个啤酒产业?

说起饮品&#xff0c;近年来中国啤酒业中各大品牌齐齐聚焦高端化的趋势绝对值得一提。然而&#xff0c;与之相反&#xff0c;国内乳业却是仍未进入高端化阶段&#xff0c;甚至陷入了周期底部中。 图源&#xff1a;中国圣牧财报 增收降利 牧企承受巨大的供需缺口压力 从产业链…...

关于模型参数融合的思考

模型参数融合通常指的是在训练过程中或训练完成后将不同模型的参数以某种方式结合起来&#xff0c;以期望得到更好的性能。这种融合可以在不同的层面上进行&#xff0c;例如在神经网络的不同层之间&#xff0c;或者是在完全不同的模型之间。模型参数融合的目的是结合不同模型的…...

Windows MySQL本地服务器设置并导入数据库和数据

文章目录 小结问题及解决导出数据库Windows MySQL本地服务器设置导入数据库和数据 参考 小结 最近需要在本地Windows环境中设置MySQL服务器&#xff0c;并导入数据库和数据&#xff0c;记录过程。 问题及解决 导出数据库 首先需要导出数据库&#xff1a; C:\mysql-8.0.37-…...

豪投巨资,澳大利亚在追逐海市蜃楼吗?

澳大利亚政府正在积极投资于量子计算领域。继2021年向量子技术投资逾1亿澳元后&#xff0c;2023年5月&#xff0c;该国发布了首个国家量子战略&#xff0c;详细阐述了如何把握量子技术的未来及保持全球领先地位。 澳大利亚的国家量子战略概述 原文链接&#xff1a; https://ww…...

面试集中营—Redis架构篇

一、Redis到底是多线程还是单线程 1、redis6.0版本之前的单线程&#xff0c;是指网络请求I/O与数据的读写是由一个线程完成的&#xff1b; 2、redis6.0版本升级成了多线程&#xff0c;指的是在网络请求I/O阶段应用的多线程技术&#xff1b;而键值对的读写还是由单线程完成的。所…...

05_kafka-整合springboot

文章目录 kafka 整合 springboot pom.xml <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.5.RELEASE</version> </parent> <dependencies>&…...

论UML在学情精准测评系统中的应用

摘要简介 项目背景&#xff1a; 随着教育改革的不断深入&#xff0c;对学生学情的精准测评成为教育教学工作中的重要环节。为了解决传统学情测评方式主观性强、效率低、反馈不及时等问题&#xff0c;我们团队受教育主管部门委托&#xff0c;承担了中小学学情精准测评系统&…...

Day23 代码随想录打卡|字符串篇---重复的子字符串

题目&#xff08;leecode T459&#xff09;&#xff1a; 给定一个非空的字符串 s &#xff0c;检查是否可以通过由它的一个子串重复多次构成。给定的字符串只含有小写英文字母&#xff0c;并且长度不超过10000。fang 移动匹配。分析可以由自己的子串构成的字符串&#xff0c;肯…...

【win10 文件夹数量和看到不一致查看隐藏文件已经打开,Thumb文件作妖】

目录 任务介绍&#xff1a;重命名规则修改前修改后 实现思路VB代码实现BUG犯罪现场&#xff08;眼见不一定为实&#xff09;破案1&#xff1a;抓顶风作案的反贼&#xff01;&#xff01;&#xff01;破案2&#xff1a;破隐身抓刺客&#xff01;&#xff01;&#xff01;杀器&am…...

ctfshow web入门 sql注入 web224--web233

web224 扫描后台&#xff0c;发现robots.txt&#xff0c;访问发现/pwdreset.php &#xff0c;再访问可以重置密码 &#xff0c;登录之后发现上传文件 检查发现没有限制诶 上传txt,png,zip发现文件错误了 后面知道群里有个文件能上传 <? _$GET[1]_?>就是0x3c3f3d60245…...

「Java开发指南」如何用MyEclipse搭建GWT 2.1和Spring?(一)

本教程将指导您如何生成一个可运行的Google Web Toolkit (GWT) 2.1和Spring应用程序&#xff0c;该应用程序为域模型实现了CRUD应用程序模式。在本教程中&#xff0c;您将学习如何&#xff1a; 安装Google Eclipse插件为GWT配置一个项目搭建从数据库表到一个现有的项目GWT编译…...

python同时进行字符串的多种替换

一些常见的方法&#xff1a; 使用str.replace()方法&#xff1a;这是一种简单的方法&#xff0c;但是如果你有多个替换需要进行&#xff0c;可能会变得很繁琐。 text "This is a sample text with some words." text text.replace("sample", "exa…...

【Java基础题型】用筛法求之N内的素数(老题型)

输入格式 N输出格式 0&#xff5e;N的素数样例输入 100样例输出 2 3 5 7 11 13 17 19 23 29 31 37 老朋友素数了属于是&#xff01; 方法1&#xff1a;(穷举法) 通过遍历 i 的所有除数&#xff0c;如果除以除数后商变成了0&#xff0c;那么把布尔值变成假的。表示不是素数 【…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...