Android的状态栏和导航栏是在SystemUI中实现的,目前还不支持手动隐藏和显示状态栏和导航栏,接下来我们将对此功能进行讲解。
在系统启动过程中,会加载SystemUI中的状态栏,具体过程在这里不予以分析,状态栏对应的类为:\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBar.java
加载这个类会首先调用它的start方法。其代码为:
@Override
public void start() {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
updateDisplaySize();
/// M: Support Smartbook Feature.
if (SIMHelper.isMediatekSmartBookSupport()) {
/// M: [ALPS01097705] Query the plug-in state as soon as possible.
mIsDisplayDevice = SIMHelper.isSmartBookPluggedIn(mContext);
Log.v(TAG, "start, mIsDisplayDevice=" + mIsDisplayDevice);
}
super.start(); // calls createAndAddWindows()
addNavigationBar();
// Lastly, call to the icon policy to install/update all the icons.
mIconPolicy = new PhoneStatusBarPolicy(mContext);
mHeadsUpObserver.onChange(true); // set up
if (ENABLE_HEADS_UP) {
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(SETTING_HEADS_UP), true,
mHeadsUpObserver);
}
}
这个方法重写了父类\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\BaseStatusBar.java的start方法和调用了一个添加NavigationBar的方法,我们这里比较关心的是父类的这个start方法,来看看他的源码:
public void start() {
mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
mWindowManagerService = WindowManagerGlobal.getWindowManagerService();
mDisplay = mWindowManager.getDefaultDisplay();
mDreamManager = IDreamManager.Stub.asInterface(
ServiceManager.checkService(DreamService.DREAM_SERVICE));
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mProvisioningObserver.onChange(false); // set up
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED), true,
mProvisioningObserver);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
mRecents = getComponent(RecentsComponent.class);
mLocale = mContext.getResources().getConfiguration().locale;
mLayoutDirection = TextUtils.getLayoutDirectionFromLocale(mLocale);
// Connect in to the status bar manager service
StatusBarIconList iconList = new StatusBarIconList();
ArrayList notificationKeys = new ArrayList();
ArrayList notifications = new ArrayList();
mCommandQueue = new CommandQueue(this, iconList);
int[] switches = new int[7];
ArrayList binders = new ArrayList();
try {
mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications,
switches, binders);
} catch (RemoteException ex) {
// If the system process isn't there we're doomed anyway.
}
createAndAddWindows();
disable(switches[0]);
setSystemUiVisibility(switches[1], 0xffffffff);
topAppWindowChanged(switches[2] != 0);
// StatusBarManagerService has a back up of IME token and it's restored here.
setImeWindowStatus(binders.get(0), switches[3], switches[4]);
setHardKeyboardStatus(switches[5] != 0, switches[6] != 0);
// Set up the initial icon state
int N = iconList.size();
int viewIndex = 0;
for (int i=0; iif (icon != null) {
addIcon(iconList.getSlot(i), i, viewIndex, icon);
viewIndex++;
}
}
// Set up the initial notification state
N = notificationKeys.size();
if (N == notifications.size()) {
for (int i=0; iget(i), notifications.get(i));
}
} else {
Log.wtf(TAG, "Notification list length mismatch: keys=" + N
+ " notifications=" + notifications.size());
}
if (DEBUG) {
Log.d(TAG, String.format(
"init: icons=%d disabled=0x%08x lights=0x%08x menu=0x%08x imeButton=0x%08x",
iconList.size(),
switches[0],
switches[1],
switches[2],
switches[3]
));
}
mCurrentUserId = ActivityManager.getCurrentUser();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(mBroadcastReceiver, filter);
}
这里实例化了一些服务类和管理类,并且对通知和系统图标做了一些初始化工作,其中调用了一个createAndAddWindows方法,这个方法做了哪些工作呢?这个一个抽象方法,那应该就是在其子类实现,我们回到PhoneStatusBar类中,果然有相应的实现
@Override
public void createAndAddWindows() {
addStatusBarWindow();
}
来看看addStatusBarWindow方法:
private void addStatusBarWindow() {
// Put up the view
final int height = getStatusBarHeight();
// Now that the status bar window encompasses the sliding panel and its
// translucent backdrop, the entire thing is made TRANSLUCENT and is
// hardware-accelerated.
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
height,
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
lp.packageName = mContext.getPackageName();
makeStatusBarView();
/// M: [SystemUI] For SystemUI AT.
if (AutoTestHelper.isNotRunningInTest()) {
mWindowManager.addView(mStatusBarWindow, lp);
isStatusBarShow = true;
}
int state = Settings.System.getInt(mContext.getContentResolver(), Settings.System.STATUSBAR_HIDE, -1);
if(state == 1){
mStatusBarWindow.setVisibility(View.GONE);
mNavigationBarView.setVisibility(View.GONE);
isStatusBarShow = false;
}
}
这里主要调用了makeStatusBarView这个方法,这个方法主要是用来构建状态栏的View
protected PhoneStatusBarView makeStatusBarView() {
if (FeatureOption.MTK_GEMINI_SUPPORT) {
mStatusBarWindow = (StatusBarWindowView)View.inflate(context, R.layout.gemini_super_status_bar, null);
} else {
mStatusBarWindow = (StatusBarWindowView) View.inflate(context, R.layout.super_status_bar, null);
}
mStatusBarView = (PhoneStatusBarView) mStatusBarWindow.findViewById(R.id.status_bar);
// Quick Settings (where available, some restrictions apply)
if (mHasSettingsPanel) {
// first, figure out where quick settings should be inflated
final View settings_stub;
if (mHasFlipSettings) {
// a version of quick settings that flips around behind the notifications
settings_stub = mStatusBarWindow.findViewById(R.id.flip_settings_stub);
if (settings_stub != null) {
mFlipSettingsView = ((ViewStub)settings_stub).inflate();
mFlipSettingsView.setVisibility(View.GONE);
mFlipSettingsView.setVerticalScrollBarEnabled(false);
}
} else {
// full quick settings panel
settings_stub = mStatusBarWindow.findViewById(R.id.quick_settings_stub);
if (settings_stub != null) {
mSettingsPanel = (SettingsPanelView) ((ViewStub)settings_stub).inflate();
} else {
mSettingsPanel = (SettingsPanelView) mStatusBarWindow.findViewById(R.id.settings_panel);
}
if (mSettingsPanel != null) {
if (!ActivityManager.isHighEndGfx()) {
mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
R.color.notification_panel_solid_background)));
}
}
}
// wherever you find it, Quick Settings needs a container to survive
mSettingsContainer = (QuickSettingsContainerView)
mStatusBarWindow.findViewById(R.id.quick_settings_container);
if (mSettingsContainer != null) {
mQS = new QuickSettings(mContext, mSettingsContainer);
if (!mNotificationPanelIsFullScreenWidth) {
mSettingsContainer.setSystemUiVisibility(
View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
| View.STATUS_BAR_DISABLE_SYSTEM_INFO);
}
if (mSettingsPanel != null) {
mSettingsPanel.setQuickSettings(mQS);
}
mQS.setService(this);
mQS.setBar(mStatusBarView);
mQS.setup(mNetworkController, mBluetoothController, mBatteryController,
mLocationController, mRotationLockController);
} else {
mQS = null; // fly away, be free
}
}
这里只列出了关键代码,实例化了一个mStatusBarView 对象,然后创建快速设置的显示面板,接着创建一个快速设置的容器,并利用这个容器来创建了一个QuickSettings对象,最后把这个对象添加到显示面板mSettingsPanel中,QuickSettings路径为:\frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\QuickSettings.java
接下来QuickSettings对象mQS调用了setup方法,来看看这个方法:
void setup(NetworkController networkController, BluetoothController bluetoothController,
BatteryController batteryController, LocationController locationController,
RotationLockController rotationLockController) {
mBluetoothController = bluetoothController;
mRotationLockController = rotationLockController;
mLocationController = locationController;
setupQuickSettings();
updateResources();
applyLocationEnabledStatus();
/// M: We control BT state in QuickSettingsConnectionModel.
///networkController.addNetworkSignalChangedCallback(mModel);
///bluetoothController.addStateChangedCallback(mModel);
batteryController.addStateChangedCallback(mModel);
/// M: Support Laptop Battery on QS.
batteryController.addLaptopStateChangedCallback(mModel);
locationController.addSettingsChangedCallback(mModel);
rotationLockController.addRotationLockControllerCallback(mModel);
}
接着进入setupQuickSettings方法:
private void setupQuickSettings() {
// Setup the tiles that we are going to be showing (including the temporary ones)
LayoutInflater inflater = LayoutInflater.from(mContext);
addUserTiles(mContainerView, inflater);
addSystemTiles(mContainerView, inflater);
addTemporaryTiles(mContainerView, inflater);
IQuickSettingsPlugin quickSettingsPlugin = PluginFactory.getQuickSettingsPlugin(mContext);
quickSettingsPlugin.customizeTileViews(mContainerView);
queryForUserInformation();
queryForSslCaCerts();
mTilesSetUp = true;
/// M: [SystemUI] Add quick settings function(airplane, data conn, bluetooth, timeout, gps, etc.) @{.
mQuickSettingsConnectionModel.buildIconViews();
new Handler().postDelayed(new Runnable() {
public void run() {
setUpdate();
mQuickSettingsConnectionModel.setUpdates(true);
mQuickSettingsConnectionModel.initConfigurationState();
}
}, 200);
/// M: [SystemUI] Add quick settings function(airplane, data conn, bluetooth, timeout, gps, etc.) @}.
}
addUserTiles方法是添加快速设置中的用户选项,addSystemTiles方法添加了Wifi,蓝牙转屏等选项
private void addSystemTiles(ViewGroup parent, LayoutInflater inflater) {
/// M: MTK Quick Setting.
addLaptopBatteryTile(parent, inflater);
addBatteryTile(parent, inflater);
addSettingTile(parent, inflater);
addWifiTile(parent, inflater);
addBluetoothTile(parent, inflater);
addLocationTile(parent, inflater);
addStatusBarTile(parent, inflater);
addAirplaneTile(parent, inflater);
addDataConnectionTile(parent, inflater);
addDataUsageTile(parent, inflater);
addAudioProfileTile(parent, inflater);
addBrightnessTile(parent, inflater);
addRotationTile(parent, inflater);
addTimeoutTile(parent, inflater);
}
在此,我们添加了一个addStatusBarTile方法,用于添加隐藏状态栏选项,代码为:
private void addStatusBarTile(ViewGroup parent, LayoutInflater inflater) {
/// M: StatusBar Tile
final QuickSettingsBasicTile statusBarTile =
new QuickSettingsBasicTile(mContext, null, R.layout.mtk_quick_settings_tile_basic);
statusBarTile.setTileViewId(QuickSettingsTileViewId.ID_StatusBar);
parent.addView(statusBarTile);
mQuickSettingsConnectionModel.addStatusBarTile(statusBarTile);
}
这里首先声明了一个statusBarTile的view对象,然后设置了这个statusBarTile的显示的标题,再把这个statusBarTile对象添加到parent也就是mContainerView中,最后把statusBarTile添加到mQuickSettingsConnectionModel对象中,看看它的源码:
public void addStatusBarTile(View statusBarView) {
mStatusBarTileView = statusBarView;
mStatusBarLayout = (FrameLayout) mStatusBarTileView.findViewById(R.id.layout);
mStatusBarIcon = (ImageView) mStatusBarTileView.findViewById(R.id.image);
}
这里很简单,只是获取隐藏状态栏选项的view,布局和image。
回到setupQuickSettings方法中,接着会创建一个子线程,在这个子线程中会调用mQuickSettingsConnectionModel对象的initConfigurationState方法,看看源码:
public void initConfigurationState() {
boolean isAirlineModeOn = isAirplaneModeOn(mContext);
if (FeatureOption.MTK_WLAN_SUPPORT) {
if (PluginFactory.getStatusBarPlugin(mContext).supportDisableWifiAtAirplaneMode()) {
mWifiStateTracker.setAirlineMode(isAirlineModeOn);
mWifiTileView.setEnabled(mWifiStateTracker.isClickable());
}
mWifiStateTracker.setImageViewResources(mContext);
}
if (FeatureOption.MTK_BT_SUPPORT) {
if (PluginFactory.getStatusBarPlugin(mContext).supportDisableBluetoothAtAirplaneMode()) {
mBluetoothStateTracker.setAirlineMode(isAirlineModeOn);
mBluetoothTileView.setEnabled(mBluetoothStateTracker.isClickable());
}
mBluetoothStateTracker.setImageViewResources(mContext);
}
mAirlineModeStateTracker.setImageViewResources(mContext);
/// M: only apply if NOT wifi-only device @{
if (!isWifiOnlyDevice()) {
/// M: }@
mMobileStateTracker.setAirlineMode(isAirlineModeOn);
mMobileStateTracker.setHasSim(false);
mMobileStateTracker.setCurrentState(mContext, StateTracker.STATE_DISABLED);
mMobileStateTracker.setImageViewResources(mContext);
mSimCardReady = SystemProperties.getBoolean(TelephonyProperties.PROPERTY_SIM_INFO_READY, false);
if (mSimCardReady) {
Xlog.d(TAG, "Oops, sim ready, maybe phone is drop down and restarted");
List.SimInfoRecord> simInfos = SIMHelper.getSIMInfoList(mContext);
if (simInfos == null || simInfos.size() <= 0) {
mMobileStateTracker.setHasSim(false);
} else {
mMobileStateTracker.setHasSim(true);
}
mMobileTileView.setEnabled(mMobileStateTracker.isClickable());
mMobileStateTracker.setImageViewResources(mContext);
}
/// M: only apply if NOT wifi-only device @{
}
/// M: }@
if (ENABLE_TIMEOUT) {
mTimeoutStateTracker.setImageViewResources(mContext);
}
mAutoRotationStateTracker.setImageViewResources(mContext);
mStatusBarStateTracker.setImageViewResources(mContext);
if (ENABLE_AUDIO_PROFILE) {
if (mProfileManager.getActiveProfileKey() != null) {
updateProfileView(AudioProfileManager.getScenario(mProfileManager.getActiveProfileKey()));
}
}
}
这个方法主要对快速设置栏中初始化的操作,我们在其中添加了mStatusBarStateTracker.setImageViewResources(mContext);
那么这个mStatusBarStateTracker是个什么呢?
它是QuickSettingsConnectionModel中的一个内部类的对象,
private final class StatusBarStateTracker extends StateTracker {
@Override
public int getActualState(Context context) {
int state = Settings.System.getInt(context.getContentResolver(), Settings.System.STATUSBAR_HIDE, -1);
if(state == -1){
state = 0;
}
if (state == 1) {
return STATE_ENABLED;
} else if (state == 0) {
return STATE_DISABLED;
} else {
return STATE_UNKNOWN;
}
}
@Override
public void onActualStateChange(Context context, Intent unused) {
/// M: Note: the broadcast location providers changed intent
/// doesn't include an extras bundles saying what the new value is.
setCurrentState(context, getActualState(context));
}
@Override
public void requestStateChange(final Context context, final boolean desiredState) {
final ContentResolver resolver = context.getContentResolver();
new AsyncTask() {
@Override
protected Boolean doInBackground(Void... args) {
Settings.System.putInt(context.getContentResolver(),
Settings.System.STATUSBAR_HIDE, desiredState ? 1 : 0);
return desiredState;
}
@Override
protected void onPostExecute(Boolean result) {
setCurrentState(context, result ? STATE_ENABLED : STATE_DISABLED);
sendHideStatusBarBroadcast(result);
}
}.execute();
}
public int getDisabledResource() {
return R.drawable.ic_qs_mobile_off;
}
public int getEnabledResource() {
return R.drawable.ic_qs_mobile_enable;
}
public ImageView getImageButtonView() {
return mStatusBarIcon;
}
@Override
public ImageView getIndicatorView() {
return null;
}
public View getTileView() {
return mStatusBarTileView;
}
}
这个内部类的作用主要就是获取并修改当前状态栏的状态(是否隐藏),具体的我们后面再分析。
在子线程中,其实还有setupQuickSettings方法的子线程中,还有一个方法我们没讲,mQuickSettingsConnectionModel.setUpdates(true);
来看看这个setUpdate方法:
public void setUpdates(boolean update) {
if (update != mUpdating) {
if (ENABLE_AUDIO_PROFILE) {
mProfileKeys = new ArrayList();
mProfileKeys = mProfileManager.getPredefinedProfileKeys();
}
mUpdating = update;
if (update) {
IntentFilter filter = new IntentFilter();
if (FeatureOption.MTK_WLAN_SUPPORT) {
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
}
if (FeatureOption.MTK_BT_SUPPORT) {
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
}
/// M: for mobile config
filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_INDICATOR_STATE_CHANGED);
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
filter.addAction(TRANSACTION_START);
filter.addAction(TRANSACTION_STOP);
filter.addAction(IPO_BOOT);
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
refreshDataUsageTile();
mContext.registerReceiver(mIntentReceiver, filter);
if (FeatureOption.MTK_GEMINI_SUPPORT) {
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.GPRS_CONNECTION_SIM_SETTING)
, true, mMobileStateChangeObserver);
} else {
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Global.MOBILE_DATA)
, true, mMobileStateForSingleCardChangeObserver);
}
/// M: get notified of phone state changes
TelephonyManager telephonyManager = (TelephonyManager) mContext
.getSystemService(Context.TELEPHONY_SERVICE);
if (FeatureOption.MTK_GEMINI_SUPPORT) {
/// M: Support GeminiPlus
for (int i = PhoneConstants.GEMINI_SIM_1; i < PhoneConstants.GEMINI_SIM_1 + PhoneConstants.GEMINI_SIM_NUM; i++) {
SIMHelper.listen(mPhoneStateListenerGemini, PhoneStateListener.LISTEN_SERVICE_STATE, i);
}
} else {
telephonyManager.listen(mPhoneStateListener1,
PhoneStateListener.LISTEN_SERVICE_STATE);
}
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.SCREEN_OFF_TIMEOUT),
true, mTimeoutChangeObserver, mUserTracker.getCurrentUserId());
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.ACCELEROMETER_ROTATION),
true, mAutoRotationChangeObserver);
mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.STATUSBAR_HIDE),
true, mStatusBarChangeObserver);
/// M: Register for Intent broadcasts for the clock and battery
Xlog.d(TAG, "setUpdates: listenAudioProfie with mAudioProfileListenr = " + mAudioProfileListenr);
if (ENABLE_AUDIO_PROFILE) {
mProfileManager.listenAudioProfie(mAudioProfileListenr, AudioProfileListener.LISTEN_AUDIOPROFILE_CHANGEG);
}
} else {
mContext.unregisterReceiver(mIntentReceiver);
if (FeatureOption.MTK_GEMINI_SUPPORT) {
mContext.getContentResolver().unregisterContentObserver(
mMobileStateChangeObserver);
} else {
mContext.getContentResolver().unregisterContentObserver(
mMobileStateForSingleCardChangeObserver);
}
TelephonyManager telephonyManager = (TelephonyManager) mContext
.getSystemService(Context.TELEPHONY_SERVICE);
if (FeatureOption.MTK_GEMINI_SUPPORT) {
/// M: Support GeminiPlus
for (int i = PhoneConstants.GEMINI_SIM_1; i < PhoneConstants.GEMINI_SIM_1 + PhoneConstants.GEMINI_SIM_NUM; i++) {
SIMHelper.listen(mPhoneStateListenerGemini, 0, i);
}
} else {
telephonyManager.listen(mPhoneStateListener1, 0);
}
mContext.getContentResolver().unregisterContentObserver(mTimeoutChangeObserver);
mContext.getContentResolver().unregisterContentObserver(mAutoRotationChangeObserver);
mContext.getContentResolver().unregisterContentObserver(mStatusBarChangeObserver);
if (ENABLE_AUDIO_PROFILE) {
mProfileManager.listenAudioProfie(mAudioProfileListenr, AudioProfileListener.LISTEN_NONE);
}
}
}
}
这里用到了ContentObserver内容观察者,用于监视快速设置中选项的变化,我们添加了如下代码:mContext.getContentResolver().registerContentObserver(
Settings.System.getUriFor(Settings.System.STATUSBAR_HIDE),
true, mStatusBarChangeObserver);
来看看mStatusBarChangeObserver的实现:
private ContentObserver mStatusBarChangeObserver = new ContentObserver(new Handler()) {
@Override
public void onChange(boolean selfChange) {
mStatusBarStateTracker.onActualStateChange(mContext, null);
mStatusBarStateTracker.setImageViewResources(mContext);
}
};
当选项状态发生改变时,mStatusBarStateTracker对象就会获取当前的 状态,并对新的状态进行设置。我们接下来分析StatusBarStateTracker:
private final class StatusBarStateTracker extends StateTracker {
@Override
public int getActualState(Context context) {
int state = Settings.System.getInt(context.getContentResolver(), Settings.System.STATUSBAR_HIDE, -1);
if(state == -1){
state = 0;
}
if (state == 1) {
return STATE_ENABLED;
} else if (state == 0) {
return STATE_DISABLED;
} else {
return STATE_UNKNOWN;
}
}
@Override
public void onActualStateChange(Context context, Intent unused) {
/// M: Note: the broadcast location providers changed intent
/// doesn't include an extras bundles saying what the new value is.
setCurrentState(context, getActualState(context));
}
@Override
public void requestStateChange(final Context context, final boolean desiredState) {
final ContentResolver resolver = context.getContentResolver();
new AsyncTask() {
@Override
protected Boolean doInBackground(Void... args) {
Settings.System.putInt(context.getContentResolver(),
Settings.System.STATUSBAR_HIDE, desiredState ? 1 : 0);
return desiredState;
}
@Override
protected void onPostExecute(Boolean result) {
setCurrentState(context, result ? STATE_ENABLED : STATE_DISABLED);
sendHideStatusBarBroadcast(result);
}
}.execute();
}
public int getDisabledResource() {
return R.drawable.ic_qs_mobile_off;
}
public int getEnabledResource() {
return R.drawable.ic_qs_mobile_enable;
}
public ImageView getImageButtonView() {
return mStatusBarIcon;
}
@Override
public ImageView getIndicatorView() {
return null;
}
public View getTileView() {
return mStatusBarTileView;
}
}
当执行onActualStateChange方法时会执行setCurrentState方法,而执行setCurrentState又会调用requestStateChange方法,
public final void setCurrentState(Context context, int newState) {
final boolean wasInTransition = mInTransition;
switch (newState) {
case STATE_DISABLED:
mInTransition = false;
mActualState = false;
break;
case STATE_ENABLED:
mInTransition = false;
mActualState = true;
break;
case STATE_TURNING_ON:
mInTransition = true;
mActualState = false;
break;
case STATE_TURNING_OFF:
mInTransition = true;
mActualState = true;
break;
default:
break;
}
if (wasInTransition && !mInTransition) {
if (mDeferredStateChangeRequestNeeded) {
Xlog.v(TAG, "processing deferred state change");
if (mActualState != null && mIntendedState != null
&& mIntendedState.equals(mActualState)) {
Xlog.v(TAG, "... but intended state matches, so no changes.");
} else if (mIntendedState != null) {
mInTransition = true;
requestStateChange(context, mIntendedState);
}
mDeferredStateChangeRequestNeeded = false;
}
}
}
在requestStateChange有个异步任务用于设置新的选项值,并发送一个广播,这个广播的作用是通知PhoneStatusBar可以隐藏或显示状态栏和导航栏了,
private void sendHideStatusBarBroadcast(boolean isStatusBarHide){
Intent intent = new Intent();
intent.putExtra("isStatusBarHide", isStatusBarHide);
intent.setAction("com.android.hide_status_bar");
mContext.sendBroadcast(intent);
}
接下来我们看看这个广播被接收后做了哪些处理。
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
else if (STATUS_BAR_HIDE_ACTION.equals(action)) {
boolean isStatusBarHide = intent.getExtras().getBoolean("isStatusBarHide");
//Log.e("dy","isStatusBarHide == "+String.valueOf(isStatusBarHide));
//Log.e("dy","isStatusBarShow == "+String.valueOf(isStatusBarShow));
if(!isStatusBarHide){
mStatusBarWindow.setVisibility(View.VISIBLE);
mNavigationBarView.setVisibility(View.VISIBLE);
isStatusBarShow = true;
Log.e("dy","show");
}
if(isStatusBarHide){
mStatusBarWindow.setVisibility(View.GONE);
mNavigationBarView.setVisibility(View.GONE);
isStatusBarShow = false;
Log.e("dy","hide");
}
}
else if (!isExpandedInvisible&&STATUS_BAR_HIDING_ACTION.equals(action)) {
boolean isStatusBarHiding = intent.getExtras().getBoolean("isStatusBarHiding");
if(!isStatusBarHiding&&!isStatusBarShow){
mStatusBarWindow.setVisibility(View.VISIBLE);
}
if(isStatusBarHiding&&!isStatusBarShow){
mStatusBarWindow.setVisibility(View.GONE);
}
}
}
这里其实挺简单,就是根据广播传过来的 属性 值,对状态栏和导航栏进行显示和隐藏。
Android快速设置中添加隐藏状态栏和导航栏选项的分析到此结束!