1. 程式人生 > >Android HOME鍵,BACK鍵的捕獲與響應

Android HOME鍵,BACK鍵的捕獲與響應

1.onUserLeaveHint

相比主頁鍵(HOME)和最近應用鍵(APP_SWITCH)的處理,返回鍵比較簡單,複寫onKeyDown就可以實現,如下:

 @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函式比較便捷,如下即可:

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

把操作寫在了exitAction函式中,這裡以啟動設定為例:

 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加許可權:

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

Activity處理:

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比較簡單,不涉及系統原始碼修改:

getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED, FLAG_HOMEKEY_DISPATCHED);
  1. 重寫此 main Activity 的 onKeyDown() 方法, 實現 home key 的處理部分, 並
return true;

Power Key稍微麻煩一些,要修改原始碼:
1: 修改 phoneWindowManager.java 的 interceptKeyBeforeQueueing 方法,在參考行後加入:

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 語句段, 並找到如下位置加入

if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) { // 參考行
if(!((result
& ACTION_PASS_TO_USER) == ACTION_PASS_TO_USER)){ //加入行
result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP; //原有程式碼
}
}
//加入行