一、新增图标资源
我这边是新增一个显示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相关的修改需要在实战中积累经验💪