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

Android HOME键,BACK键的捕获与响应

2015-03-16 10:37 507 查看

1.onUserLeaveHint

相比主页键(HOME)和最近应用键(APP_SWITCH)的处理,返回键比较简单,复写onKeyDown就可以实现,如下:

[code] @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        //  KeyEvent.KEYCODE_HOME  KeyEvent.KEYCODE_APP_SWITCH
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            exitAction();
            return true;
        } else
            return super.onKeyDown(keyCode, event);
    }


HOME和APP_SWITCH比较复杂,尤其是HOME键,如果不特殊设置,有可能会被恶意应用利用。所以即使是处理了HOME键,实测会首先进入Launcher,一段时间后才会执行我们的操作,想必这也是系统层从安全角度的考量,有时间看一下系统源码。

尝试过多种方式之后,复写onUserLeaveHint函数比较便捷,如下即可:

[code] @Override
    protected void onUserLeaveHint() {
        //super.onUserLeaveHint();
        exitAction();
    }


把操作写在了exitAction函数中,这里以启动设置为例:

[code] private void exitAction() {
        try {
            Intent intent = new Intent();
            ComponentName componentName = new ComponentName("com.android.settings",
                    "com.android.settings.Settings");
            intent.setComponent(componentName);
            startActivity(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


2.DISABLE_KEYGUARD

AndroidManifest.xml加权限:

[code]<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />


Activity处理:

[code]public class Main extends Activity {
    public static final int FLAG_HOMEKEY_DISPATCHED = 0x80000000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        this.getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED, FLAG_HOMEKEY_DISPATCHED);
        setContentView(R.layout.main);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        //  KeyEvent.KEYCODE_HOME  KeyEvent.KEYCODE_APP_SWITCH
        if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME)
            return true;
        else
            return super.onKeyDown(keyCode, event);
    }
}


3.Frameworks源码修改

Android中的Home Key,Power Key默认都是由系统的Framework来响应,如果想让自己的应用捕获响应,该怎么做呢?

Home Key比较简单,不涉及系统源码修改:

[code]getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED, FLAG_HOMEKEY_DISPATCHED);


重写此 main Activity 的 onKeyDown() 方法, 实现 home key 的处理部分, 并

[code]return true;


Power Key稍微麻烦一些,要修改源码:

1: 修改 phoneWindowManager.java 的 interceptKeyBeforeQueueing 方法,在参考行后加入:

[code]case KeyEvent.KEYCODE_POWER: { // 参考行
result &= ~ACTION_PASS_TO_USER; // 参考行
// add begin
ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
try{
if (activityManager.getRunningTasks(1).get(0).topActivity.getPackageName().equals("
your_special_package_name")){
//Please reset the special package name.
result |= ACTION_PASS_TO_USER;
Xlog.d(TAG,"detect power key in special package, pass to user!")
}
}catch(NullPointerException e){
Xlog.d(TAG,"ingore a NullPointerException ..");
}
//add end


2: 同样在此分支内, 找到 else 语句段, 并找到如下位置加入

[code]if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) { // 参考行
if(!((result
& ACTION_PASS_TO_USER) == ACTION_PASS_TO_USER)){ //加入行
result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP; //原有代码
}
}
//加入行




周木水的CSDN博客
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: