轉(zhuǎn)自:http://blog.csdn.net/codezjx/article/details/45542137
Back鍵和Home鍵的屏蔽可以看我這篇貼:http://blog.csdn.NET/codezjx/article/details/45485975
Home鍵與Recent鍵的點擊事件是在framework層進行處理的樊诺,因此onKeyDown與dispatchKeyEvent都捕獲不到點擊事件煌茬。
查看StatusBarManager.Java源碼牺堰,目前只能通過其void disable(int what) {…}設置,并可傳入值:
public static final int DISABLE_HOME = View.STATUS_BAR_DISABLE_HOME;
public static final int DISABLE_RECENT = View.STATUS_BAR_DISABLE_RECENT;
public static final int DISABLE_BACK = View.STATUS_BAR_DISABLE_BACK;
public static final int DISABLE_NONE = 0x00000000;
等等… 具體值可以查view的源碼,因為都是@hide的
首先想到了反射機制來進行調(diào)用:(或者使用移除了@hide的API 庫classes.jar)
public static final String STATUS_BAR_SERVICE = “statusbar”;
public static final String CLASS_STATUS_BAR_MANAGER = “android.app.StatusBarManager”;
public static final String METHOD_DISABLE = “disable”;
try {
Object service = getSystemService(STATUS_BAR_SERVICE);
Class <?> statusBarManager = Class.forName(CLASS_STATUS_BAR_MANAGER);
Method disable = statusBarManager.getMethod(METHOD_DISABLE, int.class);
disable.invoke (service, 0x01000000); //為View.STATUS_BAR_DISABLE_RECENT的值
} catch (Exception e) {
e.printStackTrace();
}
會報出以下錯誤提示:
Neither user 10076 nor current process has Android.permission.STATUS_BAR.
提示缺少權(quán)限帐我,Manifest添加之许赃,提示:Permission is only granted to system apps
總結(jié):通過這種方法屏蔽狀態(tài)欄下拉跟压,必須得有系統(tǒng)簽名扒袖,WTF塞茅。。僚稿。
后續(xù):參考了一些鎖屏軟件,如小米百變鎖屏蟀伸、Go鎖屏等蚀同,他們在鎖屏的時候也沒有屏蔽掉Recent鍵和狀態(tài)欄下拉缅刽。而是在點擊按鍵后迅速將彈出的Dialog和Window收回去,其實這也可以看作另一種應急解決方法蠢络。繼續(xù)回去看StatusBarManager.java源碼:發(fā)現(xiàn)了另外一個方法衰猛,public void collapse() {…}和public void expand() {…},其中collapse為收縮的方法刹孔,expand為展開方法啡省,而且調(diào)用這兩個方法不需要系統(tǒng)簽名。用上面的反射方法繼續(xù)調(diào)用之:
注意:點擊Recent鍵彈出dialog會回調(diào)onWindowFocusChanged()髓霞,因此可在該方法中調(diào)用:
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if(!hasFocus) {
……
Method collapse = statusBarManager.getMethod(METHOD_COLLAPSE);
collapse.invoke(service);
……
}
}
加入權(quán)限:
<uses-permission android:name=”android.permission.EXPAND_STATUS_BAR”/>
后面又發(fā)現(xiàn)了另一種方法卦睹,更加簡便,同樣是點擊后迅速消失(還可以隱藏長按電源的彈出框):
sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
可以通過View焦點丟失的情況下去觸發(fā)方库,發(fā)送該廣播结序,如:
class MyView extends View {
public MyView(Context pContext) {
super(pContext);
}
@Override
public void onWindowFocusChanged(boolean pHasWindowFocus) {
super.onWindowFocusChanged(pHasWindowFocus);
if (!pHasWindowFocus) {
mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
}
}
}
狀態(tài)欄的隱藏:
方法一:
// 隱藏(但點擊menu會恢復,然后又自動隱藏)
getWindow().getDecorView().setSystemUiVisibility(Window.FEATURE_ACTION_BAR_OVERLAY);
// 顯示
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
// (用這個type可以將按鈕變成小圓點:View.SYSTEM_UI_FLAG_LOW_PROFILE)
WindowManager.LayoutParams params = window.getAttributes();
params.systemUiVisibility = View.SYSTEM_UI_FLAG_LOW_PROFILE;
window.setAttributes(params);
方法二:
隱藏:進入\system\目錄纵潦,編輯build.prop徐鹤,在最后一行添加qemu.hw.mainkeys=1,保存重啟即可邀层。
顯示:改成qemu.hw.mainkeys=0返敬,保存重啟即可。
方法三:
參考一個叫GMD Hide Bar的軟件寥院。反編譯了他的源碼劲赠,他是用命令行直接干掉SystemUI這個進程來達到隱藏目的的。大家可以嘗試直接在DDMS中關閉:com.android.systemui這個進程只磷,狀態(tài)欄直接消失经磅,不過一段時間后又會自動運行。因此需要運行后臺線程不斷執(zhí)行關閉操作钮追,比較耗資源预厌,且需要root權(quán)限。
// 隱藏
int k = getPid();
if (k > 0)
ProcessUtil.execAsRoot(“kill -s CONT ” + k);
// 顯示
ProcessUtil.execAsApp(“am startservice -n com.android.systemui/.SystemUIService”);