有先时候有需求需要屏蔽状态栏下拉,例如com.android.phone中的紧急呼叫时(sim卡锁住),此时源码设计是状态栏下拉不了的。
Android中有许多隐藏的Service,StatusBarManager就是其中一个,在Context.java中可以看到:
/**
* Use with {@link #getSystemService} to retrieve a {@link
* android.app.StatusBarManager} for interacting with the status bar.
*
* @see #getSystemService
* @see android.app.StatusBarManager
* @hide
*/
public static final String STATUS_BAR_SERVICE = "statusbar";
表明该service不对外提供,如果要调用的话需要在源码上编译,才能调用到标记为@hide的接口。也可以将源码编译出来的classes.jar包添加到工程里面。
StatusBarManager提供了一些有用的接口,像disable()方法正是我们需要的,一些系统级的应用也是调用的该方法禁止StatusBar下拉的,比如电话、锁屏模块。想要调用该方法,你还需要以下权限:
获取StatusBarManager实例,
mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
禁止下拉:
mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
解除禁止:
mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
例子1:
公司有个需求当拨打电话在前台执行时,状态栏下拉不了,而在后台执行时,状态栏则可以下拉,此时需要修改的是phone应用。
在电话的呼出流程中,我们最后需要按下拨号键,才能将电话拨打出去,那么在按下拨号键之后,我们可以看到会弹出一个界面(1),显示拨号信息以及一些其他信息,这个界面就是我们的InCallScreen界面。当然,在来电(2)的时候,弹出的界面依然是InCallScreen,在我们接通电话(3)之后显示的那个界面仍然是InCallScreen。也就是说在通话过程中,我们一直可见并操作的那个界面就是InCallScreen
在类com.android.phone. InCallScreen.java
private StatusBarManager mStatusBarManager;
mStatusBarManager = (StatusBarManager)getSystemService(Context.STATUS_BAR_SERVICE);
@Override
protected void onResume() {
if (DBG) log("onResume()...");
super.onResume();
mStatusBarManager.disable(StatusBarManager.DISABLE_EXPAND);
…………………..
}
@Override
protected void onPause() {
if (DBG) log("onPause()...");
super.onPause();
mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
…………..
}
例子2:公司有个需求在安全模式下状态栏下拉不了,android模式下状态栏可以下拉(两个模式的切换广播通知),这个需求我们可以使用上述方法,也可以直接在systemui中修改,此时我们使用第二种方法。
status_bar.xml:下拉部分就是触摸这个View,因此可以在这个视图中查看触摸事件。(状态栏部分:包括浮动通知,耳机、蓝牙、电池、信号、闹钟等图标)
packagecom.android.systemui.statusbar.phone;
public classPhoneStatusBarView extends PanelBar {
@Override
public boolean panelsEnabled() { //可以在此处修改
return ((mBar.mDisabled & StatusBarManager.DISABLE_EXPAND) == 0);
}
}
上述方法中可以修改为如下:
public boolean panelsEnabled() {
if(安全模式){
return false;
}else{
return ((mBar.mDisabled &StatusBarManager.DISABLE_EXPAND) == 0);
}
}
packagecom.android.systemui.statusbar.phone;
public classPanelBar extends FrameLayout {
@Override
publicboolean onTouchEvent(MotionEvent event) {
// Allow subclasses to implement enable/disable semantics
if (!panelsEnabled()) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Slog.v(TAG,String.format("onTouch: all panels disabled, ignoring touch at(%d,%d)",
(int)event.getX(), (int) event.getY()));
}
return false;
}
public booleanpanelsEnabled() {//父类PhoneStatusBarView重写了
return true;
}
…..
}