編輯:關於Android編程
近日在研究一個視頻鎖的功能,即在 視頻播放界面上設一個鎖的功能,當該鎖起效後,就會屏蔽back, home, menu三個鍵的功能。
back 和 menu 鍵都可以通過 app層 的 onKeyDown 和 onKeyUp 函數來攔截。但是 home 鍵不行。
於是上網查了一下在app層屏蔽 home 鍵的方法。
主流的方法如下所示。但只在2.2,2.3平台下有效。(下面列舉的方法只在android 2.2, 2.3 上有效)
屏蔽Activity, Dialog風格Activity, AlertDialog的Home鍵功能方法分別是:
1.屏蔽Activity中的Home鍵功能,只需要在你要屏蔽的activity 中重寫 onAttachToWindow() 這個函數就可以了
[java]
@Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
@Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
2.屏蔽 Dialog風格Activity的Home鍵功能,也需要在你要屏蔽的activity 中重寫 onAttachToWindow() 這個函數,但設置window 的值需要改變為 TYPE_KEYGUARD_DIALOG
[java]
@Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
super.onAttachedToWindow();
}
@Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
super.onAttachedToWindow();
}
這裡之所以和Activity區分,是因為Dialog風格Activity如果用第一種方法,這個Dialog風格Activity的背景就變成黑色的,而不是透明的.
3.屏蔽AlertDialog的Home鍵功能
[java]
AlertDialog d = b.create();
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
AlertDialog d = b.create();
d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
後面通過上面一篇文章的思路來看 4.0平台的 framework 層的代碼,發現在 PhoneWindowManager.java 的 interceptKeyBeforeDispatching 函數中對home鍵的處理如下:
[java]
if (keyCode == KeyEvent.KEYCODE_HOME) {
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!
if (mHomePressed && !down) {
mHomePressed = false;
..
}
// If a system window has focus, then it doesn't make sense
// right now to interact with applications.
WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
if (attrs != null) {
final int type = attrs.type;
if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
|| type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
// the "app" is keyguard, so give it the key
return 0;
}
final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
for (int i=0; i<typeCount; i++) {
if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
// don't do anything, but also don't pass it to the app
return -1;
}
}
final int flag = attrs.flags;
if ((flag & WindowManager.LayoutParams.FLAG_HOMEKEY_DISPATCHED) != 0) {
// the window wants to handle the home key, so dispatch it to it.
return 0;
}
}
return -1;
if (keyCode == KeyEvent.KEYCODE_HOME) {
// If we have released the home key, and didn't do anything else
// while it was pressed, then it is time to go home!
if (mHomePressed && !down) {
mHomePressed = false;
......
}
// If a system window has focus, then it doesn't make sense
// right now to interact with applications.
WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
if (attrs != null) {
final int type = attrs.type;
if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
|| type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
// the "app" is keyguard, so give it the key
return 0;
}
final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
for (int i=0; i<typeCount; i++) {
if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
// don't do anything, but also don't pass it to the app
return -1;
}
}
final int flag = attrs.flags;
if ((flag & WindowManager.LayoutParams.FLAG_HOMEKEY_DISPATCHED) != 0) {
// the window wants to handle the home key, so dispatch it to it.
return 0;
}
}
return -1;
}
在此函數中,如果返回 0,則 home 鍵會交給 app 來處理,如果返回 -1 ,則不會處理 home 鍵。
在app 的你要屏蔽home 鍵的activity 中,只需要添加該標志就可以了
getWindow().addFlags(WindowManager.LayoutParams.FLAG_HOMEKEY_DISPATCHED);
如果要使home 鍵有效,再 clearFlags 即可。
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_HOMEKEY_DISPATCHED);
從上面的代碼來看,應該設置 window 的類型也是有效的,但不知為何在 4.0 中不取作用,打Log 看也不取效。不知何故。
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
作者:fulinwsuafcie
上一篇文章總結的布局優化的問題,如果對布局優化不是很熟悉的,可以看一下Android Studido下的應用性能優化總結–布局優化 , 這周一直籌劃總結一下內
轉載請注明出處:http://blog.csdn.net/singwhatiwanna/article/details/38426471(來自singwhatiwanna
Activity在窗口和ViewRootImpl創建後會請求WMS創建一個連接,請求WMS為其創建一個WindowState對象用來描述窗口狀態。Activity與WMS
Android 高德地圖 java.lang.UnsatisfiedlinkError Native method not found: com.autonavi.ama