当前位置: 首页 > 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;那么把布尔值变成假的。表示不是素数 【…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

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

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

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

Vue ③-生命周期 || 脚手架

生命周期 思考&#xff1a;什么时候可以发送初始化渲染请求&#xff1f;&#xff08;越早越好&#xff09; 什么时候可以开始操作dom&#xff1f;&#xff08;至少dom得渲染出来&#xff09; Vue生命周期&#xff1a; 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...