Android16在状态栏顶部新增图标(SystemUI)

一、新增图标资源

复制代码
我这边是新增一个显示mic被禁用的图标:
路径:
bash 复制代码
framework/base/core/res/res/drawable-nodpi/ic_mic_off.xml

首先在上面路径下新增下面我们的图标文件

xml 复制代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
  <path
      android:fillColor="@android:color/white"
      android:pathData="M11,5c0,-0.55 0.45,-1 1,-1s1,0.45 1,1v5.17l1.82,1.82c0.11,-0.31 0.18,-0.64 0.18,-0.99V5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v1.17l2,2V5zM2.81,2.81L1.39,4.22l11.65,11.65c-0.33,0.08 -0.68,0.13 -1.04,0.13 -2.76,0 -5,-2.24 -5,-5H5c0,3.53 2.61,6.43 6,6.92V21h2v-3.08c0.57,-0.08 1.12,-0.24 1.64,-0.46l5.14,5.14 1.41,-1.41L2.81,2.81zM19,11h-2c0,0.91 -0.26,1.75 -0.69,2.48l1.46,1.46C18.54,13.82 19,12.47 19,11z"/>
</vector>

然后在下面的路径添加我们的占位符,即我们图标的相应键值:

bash 复制代码
framework/base/core/res/res/values/config.xml

string-array name="config_statusBarIcons">下添加我们的占位符status_bar_no_mic

xml 复制代码
<string-array name="config_statusBarIcons">
        <item><xliff:g id="id">@string/status_bar_no_calling</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_call_strength</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_alarm_clock</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_rotate</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_headset</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_data_saver</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_ime</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_sync_failing</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_sync_active</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_nfc</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_tty</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_speakerphone</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_cdma_eri</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_data_connection</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_phone_evdo_signal</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_phone_signal</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_secure</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_managed_profile</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_connected_display</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_vpn</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_bluetooth</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_camera</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_microphone</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_location</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_mute</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_volume</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_zen</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_screen_record</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_cast</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_ethernet</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_oem_satellite</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_wifi</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_no_mic</xliff:g></item>          ----------这里是我们的
        <item><xliff:g id="id">@string/status_bar_hotspot</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_stacked_mobile</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_mobile</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_airplane</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_battery</xliff:g></item>
        <item><xliff:g id="id">@string/status_bar_sensors_off</xliff:g></item>
    </string-array>

相应的需要添加上string资源:

xml 复制代码
<string translatable="false" name="status_bar_no_mic">NoMic</string>   ----这里是我们的
    <string translatable="false" name="status_bar_rotate">rotate</string>
    <string translatable="false" name="status_bar_headset">headset</string>
    <string translatable="false" name="status_bar_data_saver">data_saver</string>
    <string translatable="false" name="status_bar_managed_profile">managed_profile</string>
    <string translatable="false" name="status_bar_ime">ime</string>
    <string translatable="false" name="status_bar_sync_failing">sync_failing</string>
    <string translatable="false" name="status_bar_sync_active">sync_active</string>
    <string translatable="false" name="status_bar_cast">cast</string>
    <string translatable="false" name="status_bar_connected_display">connected_display</string>
    <string translatable="false" name="status_bar_hotspot">hotspot</string>
    <string translatable="false" name="status_bar_location">location</string>
    <string translatable="false" name="status_bar_bluetooth">bluetooth</string>
    <string translatable="false" name="status_bar_nfc">nfc</string>
    <string translatable="false" name="status_bar_tty">tty</string>
    <string translatable="false" name="status_bar_speakerphone">speakerphone</string>
    <string translatable="false" name="status_bar_zen">zen</string>
    <string translatable="false" name="status_bar_mute">mute</string>
    <string translatable="false" name="status_bar_volume">volume</string>
    <string translatable="false" name="status_bar_wifi">wifi</string>
    <string translatable="false" name="status_bar_cdma_eri">cdma_eri</string>
    <string translatable="false" name="status_bar_data_connection">data_connection</string>
    <string translatable="false" name="status_bar_phone_evdo_signal">phone_evdo_signal</string>
    <string translatable="false" name="status_bar_phone_signal">phone_signal</string>
    <string translatable="false" name="status_bar_battery">battery</string>
    <string translatable="false" name="status_bar_alarm_clock">alarm_clock</string>
    <string translatable="false" name="status_bar_secure">secure</string>
    <string translatable="false" name="status_bar_clock">clock</string>
    <string translatable="false" name="status_bar_mobile">mobile</string>
    <string translatable="false" name="status_bar_stacked_mobile">stacked_mobile</string>
    <string translatable="false" name="status_bar_vpn">vpn</string>
    <string translatable="false" name="status_bar_ethernet">ethernet</string>
    <string translatable="false" name="status_bar_microphone">microphone</string>
    <string translatable="false" name="status_bar_camera">camera</string>
    <string translatable="false" name="status_bar_airplane">airplane</string>
    <string translatable="false" name="status_bar_no_calling">no_calling</string>
    <string translatable="false" name="status_bar_call_strength">call_strength</string>

然后在framework/base/core/res/res/values/symbols.xml里面添加我们定义的图标和占位资源:

xml 复制代码
<java-symbol type="drawable" name="ic_mic" />
<java-symbol type="string" name="status_bar_no_mic" />

二、修改framework

下面我们需要修改的文件路径为:

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java

状态栏上许多系统图标(如静音、闹钟、蓝牙等)的策略控制,都集中在 PhoneStatusBarPolicy.java 中。

java 复制代码
private final String mNoMic;  //定义占位值---接收我们前面定义的status_bar_no_mic
private boolean mNoMicVisible;

在构造函数中赋值:

java 复制代码
@Inject
    public PhoneStatusBarPolicy(StatusBarIconController iconController,
            CommandQueue commandQueue, BroadcastDispatcher broadcastDispatcher,
            @Main Executor mainExecutor, @UiBackground Executor uiBgExecutor, @Main Looper looper,
            @Main Resources resources,
            HotspotController hotspotController, BluetoothController bluetoothController,
            NextAlarmController nextAlarmController, UserInfoController userInfoController,
            RotationLockController rotationLockController, DataSaverController dataSaverController,
            ZenModeController zenModeController,
            DeviceProvisionedController deviceProvisionedController,
            KeyguardStateController keyguardStateController,
            LocationController locationController,
            SensorPrivacyController sensorPrivacyController, AlarmManager alarmManager,
            UserManager userManager, UserTracker userTracker,
            DevicePolicyManager devicePolicyManager,
            @Nullable TelecomManager telecomManager, @DisplayId int displayId,
            @Main SharedPreferences sharedPreferences, DateFormatUtil dateFormatUtil,
            RingerModeTracker ringerModeTracker,
            PrivacyItemController privacyItemController,
            PrivacyLogger privacyLogger,
            ConnectedDisplayInteractor connectedDisplayInteractor,
            ZenModeInteractor zenModeInteractor,
            JavaAdapter javaAdapter
    ) {
        //.......其他代码
        mNoMic = resources.getString(com.android.internal.R.string.status_bar_no_mic); //赋值我们的占位
        mNoMicVisible = false; //初始化状态控制变量---
    }

在init中实现我们的逻辑:禁用麦克风的时候状态栏显示出禁用麦克风的图标,麦克风可用的时候不显示图标

java 复制代码
/** Initialize the object after construction. */
    public void init() {
        // listen for broadcasts
        IntentFilter filter = new IntentFilter();
        //........其他代码
	mIconController.setIcon(mNoMic,com.android.internal.R.drawable.ic_mic_off,null);//把我们的图标和定义的占位联系起来
        IntentFilter micfilter = new IntentFilter();
        micfilter.addAction(AudioManager.ACTION_MICROPHONE_MUTE_CHANGED);//接受mic可用状态变化广播
        BroadcastReceiver mMicMuteReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updateTestIconVisibility();//更新显示状态
            }
        };
        mBroadcastDispatcher.registerReceiverWithHandler(mMicMuteReceiver, micfilter, mHandler);//注册广播
        updateTestIconVisibility();
    }

    private void updateTestIconVisibility(){
        boolean isMuted = AudioSystem.isMicrophoneMuted();//获取当前mic是否禁用,返回ture代表被禁用,false代表可用
        mNoMicVisible = isMuted;
        mIconController.setIconVisibility(mNoMic,mNoMicVisible);//设置图标是否显示
        //----这里其实我们的占位符其实就是我们的图标以及其他属性的一个唯一键值。
    }

完成效果

SystemUI相关的修改需要在实战中积累经验💪

相关推荐
胖大师5 小时前
Android Audio-FW
android
kayyoo7 小时前
CoordinatorLayout解析(二): 结合CollapsingToolbarLayout实现Toolbar折叠效果
android
数据知道8 小时前
移动端渗透测试流程:Android APK 逆向与动态调试
android·web安全·网络安全
我命由我1234510 小时前
人脸识别 - 勒克斯(光线照射到物体表面上的明亮程度)
android·java·学习·java-ee·人脸识别·学习方法·android runtime
聚美智数10 小时前
护照OCR识别-护照图像识别-护照OCR文字识别-护照识别OCR-护照信息识别-护照OCR
android·ocr
码农coding12 小时前
android12 点击桌面应用图标启动Activity流程
android
johnsong12 小时前
深度拆解:150M循环模型如何用循环推理击败大Transformer
android·深度学习·transformer
CedarQR14 小时前
云卓 G20 遥控器 Android 开发实录:从 USB 设备到读取摇杆/按键通道值
android·linux·无人机
pengyu14 小时前
【Kotlin 协程修仙录 · 炼虚境 · 初阶】 | 虚空造物:Channel 基础与协程间通信的管道艺术
android·前端·kotlin
小强闯江湖14 小时前
ViewCompose:让原生 Android View 进入声明式时代
android·开源·kotlin