Android中Home鍵的監(jiān)聽(tīng)和攔截示例
首先大家應(yīng)該先了解一種情況,就是Android在應(yīng)用中是無(wú)法攔截Home鍵的,今天我們帶大家看一下Home鍵的三種情況。
1、在應(yīng)用中按下Home鍵的邏輯處理
當(dāng)我們?cè)趹?yīng)用中按下Home鍵時(shí)界面會(huì)啟動(dòng)到桌面,我們?cè)趂rameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.Java類(lèi)中可以看到其實(shí)現(xiàn)原理,其不外乎就是調(diào)用了以下代碼。
Intent mHomeIntent; mHomeIntent = new Intent(Intent.ACTION_MAIN, null); mHomeIntent.addCategory(Intent.CATEGORY_HOME); mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); startActivity(mHomeIntent);
創(chuàng)建一個(gè)啟動(dòng)到桌面的Intent。
2、在應(yīng)用中監(jiān)聽(tīng)Home鍵
在Android應(yīng)用中如果想監(jiān)聽(tīng)Home鍵可以使用廣播機(jī)制,這個(gè)在源碼中也有體現(xiàn)。
static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
@Override
public void onReceive(Context arg0, Intent arg1) {
String action = arg1.getAction();
//按下Home鍵會(huì)發(fā)送ACTION_CLOSE_SYSTEM_DIALOGS的廣播
if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
String reason = arg1.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
if (reason != null) {
if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
// 短按home鍵
Toast.makeText(arg0, "短按Home鍵", Toast.LENGTH_SHORT).show();
} else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
// RECENT_APPS鍵
Toast.makeText(arg0, "RECENT_APPS", Toast.LENGTH_SHORT).show();
}
}
}
}
這樣就可以監(jiān)聽(tīng)Home的是否被按下。
3、在Frameworks層攔截Home鍵
在frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java文件中我們首先看一下interceptKeyBeforeDispatching()方法。
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
//......
if (keyCode == KeyEvent.KEYCODE_HOME) {
//......
handleShortPressOnHome();
}
}
//進(jìn)入handleShortPressOnHome
private void handleShortPressOnHome() {
// If there's a dream running then use home to escape the dream
// but don't actually go home.
if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {
mDreamManagerInternal.stopDream(false /*immediate*/);
return;
}
// Go home!
launchHomeFromHotKey();
}
進(jìn)入launchHomeFromHotKey方法。
static public final String SYSTEM_DIALOG_REASON_KEY = "reason";
static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
void launchHomeFromHotKey() {
if (isKeyguardShowingAndNotOccluded()) {
// don't launch home if keyguard showing
} else if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {
// when in keyguard restricted mode, must first verify unlock
// before launching home
mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {
@Override
public void onKeyguardExitResult(boolean success) {
if (success) {
try {
ActivityManagerNative.getDefault().stopAppSwitches();
} catch (RemoteException e) {
}
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
startDockOrHome();
}
}
});
} else {
// no keyguard stuff to worry about, just launch home!
try {
ActivityManagerNative.getDefault().stopAppSwitches();
} catch (RemoteException e) {
}
if (mRecentsVisible) {
// Hide Recents and notify it to launch Home
awakenDreams();
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
hideRecentApps(false, true);
} else {
// Otherwise, just launch Home
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
//啟動(dòng)Launcher界面
startDockOrHome();
}
}
}
以上方法可處理Home鍵的攔截操作,接下來(lái)我們進(jìn)入startDockOrHome方法。
void startDockOrHome() {
if (OptConfig.LC_RAM_SUPPORT) {
try {
ActivityManagerNative.getDefault().startHomePre();
} catch (RemoteException re) {
}
}
awakenDreams();
Intent dock = createHomeDockIntent();
if (dock != null) {
try {
startActivityAsUser(dock, UserHandle.CURRENT);
return;
} catch (ActivityNotFoundException e) {
}
}
//intent的相關(guān)設(shè)置
mHomeIntent = new Intent(Intent.ACTION_MAIN, null);
mHomeIntent.addCategory(Intent.CATEGORY_HOME);
mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
startActivityAsUser(mHomeIntent, UserHandle.CURRENT);
}
好啦,這里就對(duì)Home鍵進(jìn)行簡(jiǎn)單的監(jiān)聽(tīng)和攔截。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android Listview 滑動(dòng)過(guò)程中提示圖片重復(fù)錯(cuò)亂的原因及解決方法
android中l(wèi)istview是比較常見(jiàn)的組件,通過(guò)本文主要給大家分析Android中Listview滾動(dòng)過(guò)程造成的圖片顯示重復(fù)、錯(cuò)亂、閃爍的原因及解決方法,順便跟進(jìn)Listview的緩存機(jī)制,感興趣的朋友一起看下吧2016-08-08
Flutter實(shí)現(xiàn)單選,復(fù)選和開(kāi)關(guān)組件的示例代碼
在App開(kāi)發(fā)過(guò)程中,選擇交互是非常常見(jiàn)的,今天主要介紹下關(guān)于選擇的三個(gè)組件的使用:開(kāi)關(guān)、單選和復(fù)選,感興趣的小伙伴可以了解一下2022-04-04
android sdk安裝及開(kāi)發(fā)環(huán)境部署
本文給大家詳細(xì)講解了android sdk安裝方法以及android開(kāi)發(fā)環(huán)境部署方法,非常的細(xì)致全面,有需要的小伙伴務(wù)必詳細(xì)研究下。2015-11-11
Android 使用selector改變按鈕狀態(tài)實(shí)例詳解
這篇文章主要介紹了Android 使用selector改變按鈕狀態(tài)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-01-01
Android開(kāi)發(fā)中總結(jié)的Adapter工具類(lèi)【附完整源碼下載】
這篇文章主要介紹了Android開(kāi)發(fā)中總結(jié)的Adapter工具類(lèi),簡(jiǎn)單說(shuō)明了Adapter的功能,并結(jié)合實(shí)例形式分析了Adapter工具類(lèi)的相關(guān)使用方法,并附帶完整源碼供讀者下載參考,需要的朋友可以參考下2017-11-11
Android中實(shí)現(xiàn)布局背景模糊化處理的方法
這篇文章主要介紹了Android中實(shí)現(xiàn)布局背景模糊化處理的方法,需要的朋友可以參考下2015-04-04

