隐藏状态栏icon闹钟的显示
设置闹钟后在状态栏ICON区域会显示一个闹钟小图标,我们实现设置闹钟后让它不显示。
参考博客:
通过SystemUi的加载流程,我们知道有这么一个方法makeStatusBarView(result)
是创建状态栏的,找到如下代码
这里的代码主要实现了:
- 使用 CollapsedStatusBarFragment 替换 status_bar_container(状态栏通知显示区域, status_bar_container在xml文件super_status_bar.xml文件中)
- statusBarFragment.initNotificationIconArea(mNotificationIconAreaController) 初始化通知栏区域
- mStatusBarView.setBar(this) 传递statusBar处理下拉事件和mStatusBarView.setPanel(mNotificationPanel) 传递 NotificationPanelView 显示下拉UI控制
看CollapsedStatusBarFragment
在视图创建后,需要创建图标,下面这里是status_icon的创建,也就是CollapsedStatusBarFragment 类
CollapsedStatusBarFragment的onCreateView方法:
下面是视图的创建,将status_bar.xml显示创建视图到CollasedStatusBarFragment中
我们先聚集在system_icon_area区域,就是显示蓝牙、wifi、VPN、网卡icon那块区域:
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mStatusBar = (PhoneStatusBarView) view;
if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_PANEL_STATE)) {
mStatusBar.restoreHierarchyState(
savedInstanceState.getSparseParcelableArray(EXTRA_PANEL_STATE));
}
.......
mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons),
Dependency.get(CommandQueue.class));
mDarkIconManager.setShouldLog(true);
Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager);
mSystemIconArea = mStatusBar.findViewById(R.id.system_icon_area);
mClockView = mStatusBar.findViewById(R.id.clock);
showSystemIconArea(false);
showClock(false);
initEmergencyCryptkeeperText();
initOperatorName();
}
我们发现了这几行代码:
1、mDarkIconManager = new DarkIconManager(view.findViewById(R.id.statusIcons),
Dependency.get(CommandQueue.class)); //R.id.statusIcons即是system_icons.xml里面的控件。
system_icons.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/system_icons"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical">
<com.android.systemui.statusbar.phone.StatusIconContainer
android:id="@+id/statusIcons"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:paddingEnd="@dimen/signal_cluster_battery_padding"
android:gravity="center_vertical"
android:orientation="horizontal"/>
<com.android.systemui.BatteryMeterView android:id="@+id/battery"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:clipToPadding="false"
android:clipChildren="false"
systemui:textAppearance="@style/TextAppearance.StatusBar.Clock" />
</LinearLayout>
2、Dependency.get(StatusBarIconController.class).addIconGroup(mDarkIconManager); //进入其实现类StatusBarIconControllerImpl.java,在其构造函数中我们找到了实现
public StatusBarIconControllerImpl(Context context) {
super(context.getResources().getStringArray(
com.android.internal.R.array.config_statusBarIcons));
我们可以发现状态栏icon加载的图标来源于framework/base/core/res/res/values/config.xml文件
在这里我们就找到了index和slot的出处,原来在初始化的时候就已经定义好了所有的slots,然后从framework中加载出来,index就是string-array中的顺序。
<string-array name="config_statusBarIcons">
<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>
................
</string-array>
<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>
.......
然后是StatusBarIconControllerImpl.java这个控制器来控制icon的加载显示和移除。
由PhoneStatusBarPolicy.java类来负责调用执行:
有2种方式实现对ICON的控制显示和隐藏
1、首先类本身实现了大量的回调接口,通过重写这些接口类的方法,会在触发的时候被回调,然后更新ICON显示和隐藏
public class PhoneStatusBarPolicy
implements BluetoothController.Callback,
CommandQueue.Callbacks,
RotationLockControllerCallback,
Listener,
ZenModeController.Callback,
DeviceProvisionedListener,
KeyguardStateController.Callback,
LocationController.LocationChangeCallback,
RecordingController.RecordingStateChangeCallback,
TrainController.Callback{
...
2、在初始化的时候又注册了大量的监听,能够监听广播进行调节改变显示
public PhoneStatusBarPolicy(Context context, StatusBarIconController iconController) {
mContext = context;
// 初始化headset的slot
mSlotHeadset = context.getString(com.android.internal.R.string.status_bar_headset);
// listen for broadcasts
IntentFilter filter = new IntentFilter();
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(AudioManager.INTERNAL_RINGER_MODE_CHANGED_ACTION);
// 注册headset状态变化的action
filter.addAction(AudioManager.ACTION_HEADSET_PLUG);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
mContext.registerReceiver(mIntentReceiver, filter, null, mHandler);
依靠监听和回调机制,可以用来控制状态栏icon图标的显示、隐藏。在PhoneStatusBarPolicy.java中来实现,下面我们以闹钟为例,我们不希望设置闹钟之后状态栏显示闹钟icon。每个icon对应一个updatexxx(),我们找到关于闹钟的updateAlarm()
private void updateAlarm() {
final AlarmClockInfo alarm = mAlarmManager.getNextAlarmClock(UserHandle.USER_CURRENT);
final boolean hasAlarm = alarm != null && alarm.getTriggerTime() > 0;
int zen = mZenController.getZen();
final boolean zenNone = zen == Global.ZEN_MODE_NO_INTERRUPTIONS;
mIconController.setIcon(mSlotAlarmClock, zenNone ? R.drawable.stat_sys_alarm_dim
: R.drawable.stat_sys_alarm, buildAlarmContentDescription());
//mIconController.setIconVisibility(mSlotAlarmClock, mCurrentUserSetup && hasAlarm);
//jiaxian.zhang 直接修改为false
mIconController.setIconVisibility(mSlotAlarmClock, false);
}
修改后push到手机发现成功实现!