您的位置:首页 > 移动开发 > Android开发

Android 4.4、5.1、6.0 屏蔽Home键

2015-11-24 14:55 393 查看
最近项目有这样的需要所以研究了一下着块的内容.....刚开始在度娘了一大堆 要么支持2.3之前的要么是...反正都是这个复制那个没么卵用的办法..
我想先说明一点 想在应用上彻底屏蔽Home是不可能,要想屏蔽只能去改系统源码。好了,下面就看是怎么改的
首先改第一处:源码位置在frameworks\base\services\core\Java\com\Android\server\wm\WindowManagerService.java
relayoutWindow方法中找到这一段
 if (attrs != null) {
                if (win.mAttrs.type != attrs.type) {
                    Slog.e(TAG, "Window : " + win + "changes the window type!!");
                    Slog.e(TAG, "Original type : " + win.mAttrs.type);
                    Slog.e(TAG, "Changed type : " + attrs.type);
                    throw new IllegalArgumentException(
                            "Window type can not be changed after the window is added.");
                }

百度上有一种方法是复写
@Override
public void onAttachedToWindow() {
        this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
        super.onAttachedToWindow();
    }
这种方法原来的确是可以的,但是由于安全方面的原因,google已经屏蔽这个方法了,一用就会报错,要想不会报错,我们就要注释掉这里

接下来修改第二处:源码位置在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
在interceptKeyBeforeDispatching方法找到if (keyCode == KeyEvent.KEYCODE_HOME)时的处理
 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 (!down) {
                cancelPreloadRecentApps();
 
b7fe
              mHomePressed = false;
                if (mHomeConsumed) {
                    mHomeConsumed = false;
                    return -1;
                }
                if (canceled) {
                    Log.i(TAG, "Ignoring HOME; event canceled.");
                    return -1;
                }
                // Delay handling home if a double-tap is possible.
                if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) {
                    mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable); // just in case
                    mHomeDoubleTapPending = true;
                    mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
                            ViewConfiguration.getDoubleTapTimeout());
                    return -1;
                }
                handleShortPressOnHome();
                return -1;
            }

 WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
            if (attrs != null) {
                final int type = attrs.type;
                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM
                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG
                        || (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                    // 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;
                    }
                }
            }
看到这段系统会先判断窗口的类型,然后再通过handleShortPressOnHome();这个方法去返回到桌面,这就好办了,我们刚第一步已经把
WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG这个类型给开放出来了..只需要加个标记去判断要不要返回到主界面就可以了,这样子改



1:首先加个是否回到桌面的标记 
2:在要返回桌面的方法进行判断(true 返回桌面,false 不返回桌面并发送广播)
3:加个类型判断当时这个类型时我们让标记为false

到此位置我们源码的改动就完成了,最后上层要用的话只需要在要屏蔽Home键的当前Activity中复写onAttachedToWindow

@Override
public void onAttachedToWindow() {
        this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        super.onAttachedToWindow();
    }

//需要的话自己在这个地方再加个接收这个home键发出的广播
}  

涉及到的改动的java文件下载地址(已改动)
http://download.csdn.net/detail/u013286571/9902565
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: