Recent鍵及狀態欄屏蔽

FBI Warning:歡迎轉載,但請標明出處:http://blog.csdn.net/codezjx/article/details/45542137,未經本人同意請勿用於商業用途,感謝支持!

Recent鍵及狀態欄下拉的屏蔽

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的

首先想到了反射機制來進行調用:(或者使用移除了@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.

提示缺少權限,Manifest添加之,提示:Permission is only granted to system apps

總結:通過這種方法屏蔽狀態欄下拉,必須得有系統簽名,WTF。。。


後續:參考了一些鎖屏軟件,如小米百變鎖屏、GO鎖屏等,他們在鎖屏的時候也沒有屏蔽掉Recent鍵和狀態欄下拉。而是在點擊按鍵後迅速將彈出的Dialog和Window收回去,其實這也可以看作另一種應急解決方法。繼續回去看StatusBarManager.java源碼:發現了另外一個方法,public void collapse() {…}和public void expand() {…},其中collapse爲收縮的方法,expand爲展開方法,而且調用這兩個方法不需要系統簽名。用上面的反射方法繼續調用之:

注意:點擊Recent鍵彈出dialog會回調onWindowFocusChanged(),因此可在該方法中調用:

public void onWindowFocusChanged(boolean hasFocus) {
	super.onWindowFocusChanged(hasFocus);
	if(!hasFocus) {
		……
		Method collapse = statusBarManager.getMethod(METHOD_COLLAPSE);
		collapse.invoke(service);
		……
	}
}

加入權限:

<uses-permission android:name=”android.permission.EXPAND_STATUS_BAR”/></span>

後面又發現了另一種方法,更加簡便,同樣是點擊後迅速消失(還可以隱藏長按電源的彈出框):

sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));</span>

可以通過View焦點丟失的情況下去觸發,發送該廣播,如:

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));
		}
	}
}


狀態欄的隱藏:

方法一:

隱藏:(但點擊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這個進程,狀態欄直接消失,不過一段時間後又會自動運行。因此需要運行後臺線程不斷執行關閉操作,比較耗資源,且需要root權限。

隱藏:

int k = getPid();
if (k > 0)
ProcessUtil.execAsRoot(“kill -s CONT ” + k);

顯示:

ProcessUtil.execAsApp(“am startservice -n com.android.systemui/.SystemUIService”);








發佈了48 篇原創文章 · 獲贊 66 · 訪問量 45萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章