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相关的修改需要在实战中积累经验💪

相关推荐
松仔log7 小时前
Java中级——组合和继承
android·java·开发语言
我命由我1234511 小时前
Jetpack Compose - MaterialExpressiveTheme 与 MaterialTheme、ColorScheme
android·java·开发语言·java-ee·kotlin·android jetpack·android runtime
lilian23312 小时前
Harmony os 技术实战|拼豆制图06:收藏 ID、生成记录与重启恢复怎么不打架
android·java·数据库·harmonyos
2601_9557596212 小时前
ClaudeAPI成本中心与业务标签设计指南
android·java·数据库
余衫马12 小时前
2026最新版!Android Studio 极速安装与配置指南
android·ide·android studio
AFinalStone12 小时前
Android 7系统异常问题排查(五)Framework层(下)—System Server崩溃
android·tombstone·系统异常
AFinalStone12 小时前
Android 7系统异常问题排查(八)系统追踪—Trace机制与性能诊断
android·系统异常
极客猴子16 小时前
Android录音转写频繁卡顿?多款APP长时间会议场景稳定性实测
android·人工智能·智能手机·飞书
Kapaseker16 小时前
Boolean 变量到底该怎么命名?
android·kotlin
AFinalStone16 小时前
Android 7系统异常问题排查(六)应用异常(上)—ANR机制全解
android·系统异常