SystemUI

SystemUI模块

    StatusBar:通知消息提示和状态展现

    NavigationBar:返回,HOME,Recent

    KeyGuard:锁屏模块可以看做单独的应用(包括息屏与亮屏),提供基本的手机个人隐私保护

    Recents:近期应用管理,以堆叠栈的形式展现。

    Notification Panel:展示系统或应用通知内容。提供快速系统设置开关。

    VolumeUI:来用展示或控制音量的变化:媒体音量、铃声音量与闹钟音量

    截屏界面:长按电源键+音量下键后截屏,用以展示截取的屏幕照片/内容

    PowerUI:主要处理和Power相关的事件,比如省电模式切换、电池电量变化和开关屏事件等。

    RingtonePlayer:铃声播放

    StackDivider:控制管理分屏

    PipUI:提供对于画中画模式的管理

1. SystemUI相关技术介绍;嵌入式系统移植 - SystemUI : NotificationPanelView - 首次下拉和展开 QSPanel流程_iFinelio Tower 的博客-CSDN博客

2. SystemUI概述与分析

SystemUI架构分析_FamilyYuan的博客-CSDN博客_systemui

3.  Zygote进程与AMS之间的跨进程通信为什么要用Socket不用binder

参考:启动App时AMS与Zygote进程的跨进程通信过程中为什么要用Socket?_yzpbright的博客-CSDN博客

4. SystemUI博主(该博主有很多关于SystemUI的文章

参考:KeyguardBouncer启动流程_tj_shenzhendaxue的专栏-CSDN博客

StatusBar

StatusBar系统图标显示流程

 1. 显示流程图

2. 各结点调用函数解释

(1)MobileSignalController.java
    notifyListeners函数:监听系统状态,若监听到SignalCallBack反馈(即启动蓝牙了),则调用callback.setMobileDataIndicator函数;
(2)CallbackHandler.java
    setMobileDataIndicator函数:将状态值传递到 StatusBarSignalPolicy类中解析显示;
(3)StatusBarSignalPolicy.java
    setMobileDataIndicator函数:对图标状态进行赋值;
(4)StatusBarIconControllerImpl.java
    setMobileIcons函数:设置手机状态图标(例如:蓝牙)
(5)StatusBarIconController.java
    applyMobileState函数:将设置好的图标应用到状态栏
(6)StatusBarMobileView.java
    updateState函数:更新当前状态栏的显示效果

3. 参考文章

        SystemUI 的信号栏修改以及配置流程(过程较为完整

                网址:https://blog.csdn.net/kongbaidepao/article/details/88719985

        图标显示流程:

                网址:https://www.bbsmax.com/A/LPdooR3yd3/

        SystemUI状态栏(该博主讲解比较全,好几篇文章

        参考:Android SystemUI之StatusBar,状态栏(二)_肖岩-CSDN博客

        SystemUI状态栏启动流程

        参考:状态栏SystemUI的启动过程_Android专栏-CSDN博客

        状态栏图标更新流程分析

        参考:Android的StatusBar分析 - 智行无疆 - 博客园

        状态栏StatusIcon加载流程

        参考:SystemUI之状态栏status icon加载流程 - 简书

        状态栏多图标成点

        参考:Android Q : 适配状态栏图标(图标过多时显示一个点)_AiHH的博客-CSDN博客

        状态栏反色

        参考:安卓11状态栏图标不显示问题调查_书虫-CSDN博客

        深入理解Android(一本书 讲解了SystemUI等内容)

        参考:7.1.3 理解IStatusBarService · 深入理解Android 卷III · 看云

自动亮度调节快捷设置

        内容:三方apk中如何在下拉状态栏中添加自动亮度调节快捷设置

        参考: https://blog.csdn.net/xiangzaixiansheng/article/details/87618305

QS亮度调节初始化流程

StatusBar(状态栏)显示界面

ViewStub控件

        参考:ViewStub基本用法_Q 的博客-CSDN博客_viewstub

       1. config_showOperatorNameInStatusBar属性

        状态栏显示运营商信息:将该属性设置为true;

       2. include标签

        使用include显示悬浮式通知布局

状态栏主要控件

系统图标控件

         1. 定义图标的资源文件

         "xliff:g"标签

        参考:"xliff:g"标签_会飞的鱼~的博客-CSDN博客

Notification通知栏

1. 管理流程-SystemServer进程

        在SystemServer进程中对Notification处理流程如下:

        

参考文章 

        Android通知系统源码解析_PPLLiang的博客-CSDN博客

通知栏相关函数与类的解析

        Android SystemUI组件(04)状态栏-Notification显示&管理_wangdsh的博客-CSDN博客 

下拉通知栏源码分析

        SystemUI下拉通知栏的源码分析_u010823818的博客-CSDN博客

 下拉通知栏简介

       SystemUI 下拉通知栏快捷键加载流程_tj_shenzhendaxue的专栏-CSDN博客

SystemUI博主

        忘冻鱼的博客_SystemUI_Fisher_CSDN博客

SystemUI简介即SystemUI启动流程

        Android9.0 SystemUI 简介篇 (一) - dinghmcn's blog

修改下拉通知栏尺寸

        Android系统定制之SystemUI修改:下拉通知栏尺寸【转】 - 请给我倒杯茶 - 博客园

【Android系统源码修改】Android系统定制之SystemUI修改:下拉通知栏尺寸_Bright的博客-CSDN博客

1. super_status_bar.xml解析

        Android P SystemUI之super_status_bar.xml解析_Sunxiaolin2016的博客-CSDN博客

2. status_bar.xml解析

    Android P SystemUI之StatusBar UI布局status_bar.xml解析_Sunxiaolin2016的博客-CSDN博客

------------------------SystemServer进程对Notification的处理流程理解 start----------------------------------

## 用户进程创建通知-start

NotificationManager.getSystemService()函数

        参考:Android的getSystemService总结和具体使用方法 - 壮汉请留步 - 博客园

NotificationChannel类

        参考:NotificationChannel 适配填坑指南 - 简书

        功能与应用:https://blog.csdn.net/yh18668197127/article/details/86299290

## 用户进程创建通知-end

SystemServer进程对通知的处理流程中的各节点功能解析(*)

        参考:Android 发送通知Framework处理流程_闯荡_脚印-CSDN博客

Notification运行机制

        https://blog.csdn.net/silvia0427/article/details/8313396

NotificationListenerService使用详解

        NotificationListenerService使用详解_一个炮哥的博客-CSDN博客_notificationlistenerservice

INotificationManager.Stub详解

        AIDL,在Stub类中的asInterface函数_浅学误人的博客-CSDN博客

从INotificationManager.enqueueNotificationWithTag到NotificationManagerService类,其中跳转的原理,即aidl中Stub的运行机制

        AIDL,在Stub类中的asInterface函数_浅学误人的博客-CSDN博客

------------------------SystemServer进程对Notification的处理流程理解 end---------------------------------- 

2. 显示流程-SystemServer进程

-----------------------------SystemUI进程对Notification的处理流程理解 start----------------------------------

22 RemoteView的理解

        第五章、理解RemoteView_sp不会玩ps-CSDN博客(特别注意apply与reqpply()的使用)

-----------------------------SystemUI进程对Notification的处理流程理解 end-----------------------------------

KeyGuard锁屏界面

隐藏锁屏界面照相机与电话按钮

        Android_LockScreen.org · vimchan/ldk - Gitee.com

Keyguard视图布局

        参考:android4.4 Keyguard 锁屏之----布局篇_yiersanxuexi的博客-CSDN博客

        参考:Android6.0锁屏源码分析之界面布局分析_fanfan-CSDN博客_android 锁屏源码

        对布局中的小控件讲的很详细:

        Android-Keyguard开发分析(持续...)_伪程序猿的专栏-CSDN博客

 KeyGuard滑动解锁流程(锁屏解锁流程结构分析比较清晰

        Android8.1 SystemUI Keyguard之滑动解锁流程_测试0901-1-CSDN博客

Keyguard从SystemServer开始的部分流程(重要

        注:很多教程都没有讲解启动Keyguard服务的部分,这里讲了,作为补充;

        KeyguardBouncer启动流程_tj_shenzhendaxue的专栏-CSDN博客

KeyGuard 启动流程分析

        Android8.1 SystemUI Keyguard之启动流程_测试0901-1-CSDN博客

Keyguard锁屏原理解析(对视图和相关类的功能解析比较详细

        https://blog.csdn.net/qinjuning/article/details/7505703

KeyGuard解锁流程(较为详细

        Android O(8.0) Keyguard解锁流程 - 程序员大本营

Android解锁屏机制详解

        Android4.0开发之Keyguard解锁屏机制详解 - 博客 - 编程圈

Keuguard Pin码解锁流程(对于解锁部分的代码功能讲解比较详细

        android PIN码解锁流程 - JavaShuo

下拉菜单结构解析

        Android SystemUI之下拉菜单,通知栏,快捷面板(三)_肖岩-CSDN博客

VolumeUI音量界面

VolumeUI流程各函数功能详解(该博主有一个SystemUI专栏)(重要)

        VolumeUI(1):MVP框架_renshuguo123723的博客-CSDN博客

Volume流程函数功能解析(对上述博客的一个补充,结合起来理解)(重要)

        Android音量调节(二)音量处理及UI刷新_作茧自缚丶的博客-CSDN博客

Volume音量控制原理(原理清晰

        https://www.iteye.com/blog/wx1568444409-2456303

Volume音量键处理流程(对于VolumeUI的前置知识讲解的较为清晰)

   Android音量调节(一)音量键的处理流程_作茧自缚丶的博客-CSDN博客_android音量调节流程

修改系统音量条UI(测试成功

        Android 修改系统音量条UI_qq_25094789的博客-CSDN博客_android 音量条

VolumeUI分析

        SystemUI之VolumeUI分析 - Android开发 - 找一找教程网

VolumeUI启动流程(几个方法的代码详细分析)

        SystemUI之VolumeUI启动流程 - 简书

VolumeDialogControllerImpl.java # onVolumeChangedW() (音量界面更新)中使用的AudioManager常量的含义

        Android AudioManager探索_无名的一棵小树-CSDN博客

VolumeDialogControllerImpl.java # redister() # setVolumePolicy()(设置音量模式)

        AndroidQ 设置静音模式后按音量上键不能调节音量大小_u010869159的博客-CSDN博客

Android音视频(MediaSessionManager)

        Android音视频API(android.media.session):概览_一世豁然的专栏-CSDN博客

PowerUI

PowerUI启动流程

        SystemUI之PowerUI启动流程 - 简书

PowerUI分析

        system ui powerUI_jason的笔记-CSDN博客

PowerUI流程分析(函数内具体含义说明较为详细)

        Android9.0 SystemUI PowerUI 篇 (二) - dinghmcn's blog

maybeShowBateryWarning()、PowerNotificationWarnings类

        Android10 低电量通知_Aaron121314的博客-CSDN博客

<think>我们正在处理一个Android系统开发的问题:用户希望在设备开机时禁用音量条弹出。 根据Android系统架构,音量条通常由系统UI(SystemUI)控制,在音量键被按下时触发。因此,我们需要找到一种方法来阻止在开机时(或任何其他时候)弹出音量条。 思路: 1. 修改系统UI的代码,使其在检测到开机阶段时不显示音量条。 2. 或者,修改音量键事件的分发,在开机阶段忽略音量键事件。 但是,用户要求的是在开机时禁用,所以我们可能需要在系统启动过程中设置一个标志,然后根据这个标志来决定是否显示音量条。 然而,我们注意到,在开机过程中,系统会进行一系列初始化,包括媒体服务的启动。在媒体服务准备好之前,按下音量键可能会触发音量条,但此时媒体服务可能还未准备好,所以系统可能会显示铃声或通话音量条。 另一种思路:在系统启动完成之前,禁用音量键事件。我们可以通过修改PhoneWindowManager或InputManager相关代码,在启动过程中忽略音量键事件。 具体步骤: 在Android系统中,按键事件的处理始于InputManager,然后分发到WindowManagerService,最终到达PhoneWindowManager。PhoneWindowManager负责处理系统级别的按键行为。 因此,我们可以修改PhoneWindowManager,在系统启动完成(即收到ACTION_BOOT_COMPLETED广播)之前,不处理音量键事件。 但是,注意:系统启动完成广播(ACTION_BOOT_COMPLETED)是在系统启动完成后发送的,而在此之前,用户可能已经看到了音量条。因此,我们需要更早地控制音量键。 实际上,系统启动过程中,有一个阶段是“safe mode"(安全模式),但这不是我们需要的。我们可以使用系统服务(如PowerManagerService)中的启动标志,或者使用系统属性(system property)来标记启动状态。 在PhoneWindowManager中,有一个方法interceptKeyBeforeDispatching(),我们可以在这里拦截按键事件。 我们可以这样实现: 在系统启动过程中(比如从开机到桌面启动完成),设置一个标志,这个标志可以通过系统服务(如ActivityManagerService)的状态来判断。但是,在PhoneWindowManager中,我们可以通过系统服务来获取启动状态。 然而,更简单的方式是:在SystemServer启动过程中,设置一个全局标志,然后PhoneWindowManager可以访问这个标志。 但是,修改SystemServer可能涉及较多,我们考虑在PhoneWindowManager中自己监听启动状态。 实际上,PhoneWindowManager已经有一个监听启动完成的方法:在启动完成时,会调用systemBooted()方法。我们可以利用这个。 在PhoneWindowManager中,有一个变量mSystemBooted,它在systemBooted()方法中被设置为true。 因此,我们可以修改PhoneWindowManager的interceptKeyBeforeDispatching方法,在系统未启动完成(!mSystemBooted)时,对音量键事件返回一个很长的超时(这样系统就会延迟处理,直到超时,而实际上我们不希望它处理,所以返回一个很大的值,比如Long.MAX_VALUE,这样系统会等待很长时间,相当于忽略),或者直接拦截,返回0(表示我们已经处理了事件,不继续分发)。 但是,根据Android源码,interceptKeyBeforeDispatching的返回值是long类型,表示需要延迟的时间(毫秒),如果返回0,表示立即处理(但不会阻止事件继续分发?),返回-1表示不处理(立即传递给应用)。但是,实际上,如果我们想拦截事件,使其不触发音量条,我们可以返回一个很大的延迟值,这样在延迟时间内,如果事件再次发生,可能会被合并?或者我们可以直接消耗掉这个事件? 然而,更好的方法是:在系统未启动完成时,直接消耗掉音量键事件,使其不触发任何操作。 我们可以这样:在interceptKeyBeforeDispatching方法中,如果系统未启动完成,并且是音量键事件,则返回-1(表示我们不处理,但事件也不会被传递给应用?)?但是,我们需要查看标准行为。 实际上,在PhoneWindowManager中,对于音量键事件,在未启动完成时,我们可以跳过其默认处理。 具体代码修改(基于AOSP源码,路径通常为frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java): 在interceptKeyBeforeDispatching方法中,添加如下代码: ```java if (!mSystemBooted && (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP)) { // 在系统未启动完成时,拦截音量键事件 return -1; } ``` 但是,返回-1是什么意思?根据注释: * @return Returns 0 if the event should be immediately dispatched; * otherwise, returns the desired delay in nanoseconds before * dispatching. The event may be canceled if it is no longer * valid by the time the delay has expired. 实际上,返回-1表示不处理,事件会被丢弃?但根据文档,返回-1表示事件不会被传递给应用,但也不会被立即处理(而是延迟,但延迟为负数?)。所以,我们可能应该返回一个很大的正数(比如Long.MAX_VALUE)来无限延迟,直到事件被取消? 但是,在AOSP中,对于电源键在未启动完成时,是这样处理的: ```java if (!mSystemBooted) { if (down) { // 在启动完成前,按下电源键,则显示关闭选项菜单(或关机对话框) // ... 省略代码 } return -1; } ``` 我们看到,对于电源键,在未启动完成时,按下事件会触发关机菜单,然后返回-1。那么,对于音量键,我们也可以返回-1,表示我们消耗了事件(不传递给应用),并且也不会触发系统默认的音量调整。 因此,我们修改为: ```java if (!mSystemBooted) { if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { // 在系统未启动完成时,拦截音量键事件,不进行任何处理 Slog.i(TAG, "Volume key is blocked before system booted."); return -1; } } ``` 这样,在系统启动完成之前,音量键事件将被拦截,不会触发音量条弹出。 但是,请注意:在系统启动过程中,可能有其他服务(如恢复模式、recovery等)也会使用音量键,所以我们需要确保这种修改不会影响这些场景。通常,在正常启动过程中,PhoneWindowManager只会在正常系统启动后才会被初始化并开始处理事件。因此,这个修改应该是安全的。 另一种方法:修改SystemUI中音量控制器的代码,在启动完成前不显示。但这样修改可能更复杂,因为音量条由SystemUI管理,而SystemUI启动相对较早。而且,我们需要修改SystemUI的代码,并确保在启动完成前不显示。 考虑到修改PhoneWindowManager可以拦截按键事件,从而根本阻止触发音量调整,这样SystemUI就不会收到显示音量条的请求。因此,修改PhoneWindowManager可能更直接。 实现步骤: 1. 找到PhoneWindowManager.java文件(路径:frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java) 2. 在interceptKeyBeforeDispatching方法中,添加上述代码块。 注意:不同Android版本可能代码位置略有不同,但思路一致。 另外,我们还可以考虑在系统设置中增加一个开关,但用户要求的是开机时禁用,所以上述修改已经满足。 但是,用户可能希望即使在启动完成后,在某些情况下也禁用音量条?但问题要求是“开机时”,所以上述修改应该足够。 编译并刷入系统。 注意:这是一个系统级的修改,需要重新编译系统镜像,并且需要设备的root权限或厂商支持。 另外,我们也可以考虑通过其他方法,例如使用无障碍服务或设备管理员API来禁用音量键,但这些方法通常无法在系统启动过程中生效,而且需要用户手动启用,所以不满足开机时禁用的要求。 因此,推荐修改系统源码的方法。 由于用户没有提供具体的Android版本,以上代码基于较新的AOSP版本(如Android 10+)。在旧版本中,方法名和参数可能略有不同,但思路相同。 最后,生成相关问题。 注意:用户要求生成相关问题,并且回答中引用的段落末尾添加引用标识(但我们没有引用外部内容,所以不需要添加)。但是,我们参考了Android源码,可以标注。 引用[1]: frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java [^1]</think>在 Android 系统启动时禁用音量条弹出,需要修改系统级代码。以下是实现步骤和代码修改方案: ### 修改步骤 1. **定位关键代码文件** 音量控制逻辑位于 `frameworks/base/services/core/java/com/android/server/audio/AudioService.java` 和 `frameworks/base/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java`。 2. **修改 AudioService** 在 `AudioService.java` 中添加启动标志检测,阻止音量条弹出: ```java // 在 onSystemReady() 方法中添加 public void onSystemReady() { // ...原有代码... if (isBooting()) { // 系统启动中 disableVolumePopup(); // 禁用音量弹窗 } } private void disableVolumePopup() { // 关键代码:设置系统属性或全局标志 SystemProperties.set("sys.boot_completed.volume_lock", "true"); } ``` 3. **修改 VolumeDialogControllerImpl** 在 `VolumeDialogControllerImpl.java` 中检测启动标志: ```java // 在 shouldShowVolumeDialog() 方法中添加检测 private boolean shouldShowVolumeDialog() { // 检测启动锁 if ("true".equals(SystemProperties.get("sys.boot_completed.volume_lock"))) { return false; // 禁止显示 } // ...原有逻辑... } ``` 4. **清除启动标志** 在系统启动完成后(例如 `BOOT_COMPLETED` 广播中)清除标志: ```java // 在广播接收器中添加 if (Intent.ACTION_BOOT_COMPLETED.equals(action)) { SystemProperties.set("sys.boot_completed.volume_lock", "false"); } ``` ### 完整调用流程 ```mermaid graph TD A[系统启动] --> B{AudioService.onSystemReady} B -->|设置启动锁| C[SystemProperties.set] C --> D[音量键触发] D --> E{VolumeDialogControllerImpl.shouldShowVolumeDialog} E -->|检测启动锁| F[返回 false] F --> G[禁止弹窗] H[BOOT_COMPLETED 广播] --> I[清除启动锁] ``` ### 注意事项 1. **系统签名要求** 此修改需要系统级签名,普通应用无法修改 `SystemProperties`。 2. **兼容性处理** 不同 Android 版本可能需要调整: ```java // Android 12+ 需适配新音频框架 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { mAudioManager.setVolumeController(null); // 禁用默认控制器 } ``` 3. **测试场景** 需验证以下情况: - 冷启动/热启动 - 媒体/通话音量分离场景 - 无障碍模式下的兼容性 ### 替代方案(无需修改系统) ```xml <!-- 在设备管理员应用中声明权限 --> <uses-permission android:name="android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER"/> ``` 通过 `DevicePolicyManager.setVolumeKeyLongPressListener()` 拦截长按事件,但**无法完全阻止短按触发**。 [^1]: 修改基于 AOSP 代码分析,具体路径:`frameworks/base/services/audio/AudioService.java` [^2]: 系统属性控制参考:`SystemProperties.set()` 的跨进程同步特性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值