付費(fèi)下載
下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】androidHOME點(diǎn)擊事件的獲取
首先聲明我是做系統(tǒng)開發(fā)的(高通平臺(tái)),所以下面介紹的方法并不適合應(yīng)用開發(fā)者。
最經(jīng)有個(gè)需求要屏蔽HOME按鍵返回桌面并且實(shí)現(xiàn)自己的功能,發(fā)現(xiàn)以前的方式報(bào)錯(cuò)用不了,上網(wǎng)搜索了一下,發(fā)現(xiàn)都是抄來(lái)抄去基本是無(wú)用的。網(wǎng)上的方法不外乎這幾種:
第一,大家最常用的重寫onAttachedToWindow()方法,然后在HOME點(diǎn)擊事件KeyEvent.KEYCODE_HOME中做自己想做的事情,但是這個(gè)方法google處于安全考慮在android2.3.3之后就不支持了。
第二,抓取系統(tǒng)log日志,判斷有沒有打印“ent.category.HOME”信息來(lái)獲得是否按下了HOME按鍵,這樣做就算代碼知道是按下HOME鍵,那怎么阻止返回桌面呢?這只能是截獲HOME按鍵,并不能屏蔽它返回桌面的功能。
第三,修改framework源碼,在PhoneWindowManager中處理HOME按鍵的地方發(fā)送一個(gè)消息,然后在上層應(yīng)用中捕獲這個(gè)消息,這和上面是一樣的,只能截獲HOME按鍵,并不能阻止返回桌面的動(dòng)作。
第四,
在setContentView之前getWindow().setFlags(FLAG_HOMEKEY_DISPATCHED,FLAG_HOMEKEY_DISPATCHED);這個(gè)FLAG_HOMEKEY_DISPATCHED其實(shí)是個(gè)標(biāo)志位,是個(gè)常量,值為0x80000000,這個(gè)方法確實(shí)可以,但僅限于MTK(聯(lián)發(fā)科)平臺(tái)的系統(tǒng),因?yàn)镸TK自己實(shí)現(xiàn)了一套機(jī)制來(lái)規(guī)避HOME按鍵,而其它的平臺(tái),如高通、博通、展迅的代碼中是沒有加這個(gè)屬性的,所以也不行。
還有極少數(shù)思路很極端的方式,看上去都覺得很繁瑣,根本沒耐心細(xì)看。
現(xiàn)在介紹我的思路,首先還是復(fù)寫onAttachedToWindow()方法,具體代碼是在activity中加入這一段:@OverridepublicvoidonAttachedToWindow(){
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
結(jié)果當(dāng)然是一進(jìn)入這個(gè)activity就報(bào)錯(cuò),logcat查看錯(cuò)誤信息,報(bào)的錯(cuò)誤是"Windowtypecannotbechangedafterthewindowisadded.",發(fā)現(xiàn)是WindowManagerService.java中報(bào)的錯(cuò),源碼位置frameworks/base/services/java/com/android/server/wm/WindowManagerService.java,具體代碼段是relayoutWindow方法中判斷窗口類型的時(shí)候報(bào)錯(cuò):
if(attrs!=null){
if(win.mAttrs.type!=attrs.type){
thrownewIllegalArgumentException(
"Windowtypecannotbechangedafterthewindowisadded.");
}
flagChanges=win.mAttrs.flags^=attrs.flags;
attrChanges=win.mAttrs.copyFrom(attrs);
if((attrChanges&(WindowManager.LayoutParams.LAYOUT_CHANGED
|WindowManager.LayoutParams.SYSTEM_UI_VISIBILITY_CHANGED))!=0){
win.mLayoutNeeded=true;
}
}
剛才說了,google可能是出于安全原因不能讓你把窗口類型設(shè)為WindowManager.LayoutParams.TYPE_KEYGUARD了,設(shè)置了就報(bào)錯(cuò),要屏蔽這個(gè)錯(cuò)誤只需要把if(win.mAttrs.type!=attrs.type){
thrownewIllegalArgumentException(
"Windowtypecannotbechangedafterthewindowisadded.");
}注釋掉就行了,再次運(yùn)行就不會(huì)報(bào)錯(cuò)了,但是按HOME鍵還是返回桌面。繼續(xù)看分發(fā)HOME按鍵事件的代碼,源碼位置frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java中的if(keyCode==KeyEvent.KEYCODE_HOME){...}中,這里就是處理上層用戶按下HOME鍵的代碼,在里面會(huì)看到//Ifasystemwindowhasfocus,thenitdoesn'tmakesense
//rightnowtointeractwithapplications.
WindowManager.LayoutParamsattrs=win!=null?win.getAttrs():null;
if(attrs!=null){
finalinttype=attrs.type;
if(type==WindowManager.LayoutParams.TYPE_KEYGUARD
||type==WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG){
//the"app"iskeyguard,sogiveitthekey
return0;
}
finalinttypeCount=WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
for(inti=0;i<typeCount;i++){
if(type==WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]){
//don'tdoanything,butalsodon'tpassittotheapp
return-1;
}
}
}這一段代碼,意思就是如果設(shè)置了窗口類型為
WindowManager.LayoutParams.TYPE_KEYGUARD(值為2004)或者WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG,那就return0,交給用戶自己處理,不返回桌面,否則返回-1,返回桌面。通過打log發(fā)現(xiàn)代碼確實(shí)是return0,但還是返回桌面,后來(lái)才發(fā)現(xiàn)還有方法在返回桌面:/**
*Ahomekey->launchhomeactionwasdetected.
Taketheappropriateaction
*giventhesituationwiththekeyguard.
*/
voidlaunchHomeFromHotKey(){
if(mKeyguardMediator!=null&&mKeyguardMediator.isShowingAndNotHidden()){
//don'tlaunchhomeifkeyguardshowing
}elseif(!mHideLockScreen&&mKeyguardMediator.isInputRestricted()){
//wheninkeyguardrestrictedmode,mustfirstverifyunlock
//beforelaunchinghome
mKeyguardMediator.verifyUnlock(newOnKeyguardExitResult(){
publicvoidonKeyguardExitResult(booleansuccess){
if(success){
try{
ActivityManagerNative.getDefault().stopAppSwitches();
}catch(RemoteExceptione){
}
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
startDockOrHome();
}
}
});
}else{
//nokeyguardstufftoworryabout,justlaunchhome!
try{
ActivityManagerNative.getDefault().stopAppSwitches();
}catch(RemoteExceptione){
}
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
startDockOrHome();
}
}不知道高通怎么改的,就算return0也會(huì)執(zhí)行這個(gè)方法,也會(huì)返回桌面,因?yàn)檫@個(gè)方法在判斷窗口類型前面調(diào)用,現(xiàn)在要做的就簡(jiǎn)單了,只需要加個(gè)判斷,就可以屏蔽返回HOME了:booleanisGoHome=true;
WindowManager.LayoutParamsattrs=win!=null?win.getAttrs():null;
if(attrs!=null){
finalinttype=attrs.type;
if(type==WindowManager.LayoutParams.TYPE_KEYGUARD){
isGoHome=false;
}
}
//Gohome!
if(isGoHome){
launchHomeFromHotKey();
}整個(gè)HOME按鍵的代碼段://Firstwealwayshandlethehomekeyhere,soapplications
//canneverbreakit,althoughifkeyguardison,wedolet
//ithandleit,becausethatgivesusthecorrect5second
//timeout.
if(keyCode==KeyEvent.KEYCODE_HOME){
//Ifwehavereleasedthehomekey,anddidn'tdoanythingelse
//whileitwaspressed,thenitistimetogohome!
if(!down){
cancelPreloadRecentApps();
mHomePressed=false;
if(mHomeConsumed){
mHomeConsumed=false;
return-1;
}
if(canceled){
Log.i(TAG,"IgnoringHOME;eventcanceled.");
return-1;
}
//Ifanincomingcallisringing,HOMEistotallydisabled.
//(TheuserisalreadyontheInCallScreenatthispoint,
//andhisONLYoptionsaretoanswerorrejectthecall.)
try{
ITelephonytelephonyService=getTelephonyService();
if(telephonyService!=null&&telephonyService.isRinging()){
Log.i(TAG,"IgnoringHOME;there'saringingincomingcall.");
return-1;
}
}catch(RemoteExceptionex){
Log.w(TAG,"RemoteExceptionfromgetPhoneInterface()",ex);
}
//Delayhandlinghomeifadouble-tapispossible.
if(mDoubleTapOnHomeBehavior!=DOUBLE_TAP_HOME_NOTHING){
mHandler.removeCallbacks(mHomeDoubleTapTimeoutRunnable);//justincase
mHomeDoubleTapPending=true;
mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
ViewConfiguration.getDoubleTapTimeout());
return-1;
}
booleanisGoHome=true;
WindowManager.LayoutParamsattrs=win!=null?win.getAttrs():null;
if(attrs!=null){
finalinttype=attrs.type;
if(type==WindowManager.LayoutParams.TYPE_KEYGUARD){
isGoHome=false;
}
}
//Gohome!
if(isGoHome){
launchHomeFromHotKey();
}
return-1;
}
//Ifasystemwindowhasfocus,thenitdoesn'tmakesense
//rightnowtointeractwithapplications.
WindowManager.LayoutParamsattrs=win!=null?win.getAttrs():null;
if(attrs!=null){
finalinttype=attrs.type;
if(type==WindowManager.LayoutParams.TYPE_KEYGUARD
||type==WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG){
//the"app"iskeyguard,sogiveitthekey
return0;
}
finalinttypeCount=WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
for(inti=0;i<typeCount;i++){
if(type==WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]){
//don'tdoanything,butalsodon'tpassittotheapp
return-1;
}
}
}
//Rememberthathomeispressedandhandlespecialactions.
if(repeatCount==0){
mHomePressed=true;
i
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 中學(xué)學(xué)生社團(tuán)活動(dòng)經(jīng)費(fèi)預(yù)算制度
- 養(yǎng)老院定期體檢制度
- 企業(yè)內(nèi)部保密工作責(zé)任追究制度
- 公共交通車輛安全檢查制度
- 2026年工業(yè)制造中的6S管理與效率提升題解
- 2026年公務(wù)員考試模擬題行政職業(yè)能力測(cè)驗(yàn)與申論練習(xí)
- 2026年航空航天基礎(chǔ)知識(shí)學(xué)習(xí)入門與實(shí)踐題庫(kù)
- 2026年體育訓(xùn)練與健康管理測(cè)試題目
- 2026年企業(yè)管理實(shí)務(wù)能力測(cè)試題
- 2026年版權(quán)侵權(quán)監(jiān)測(cè)協(xié)議(實(shí)時(shí)·發(fā)現(xiàn)版)
- 服務(wù)外包人員保密管理制度(3篇)
- 成都高新區(qū)桂溪街道公辦幼兒園招聘編外人員考試備考題庫(kù)及答案解析
- 2025年醫(yī)院病歷管理操作規(guī)范
- 2026云南保山電力股份有限公司校園招聘50人筆試備考題庫(kù)及答案解析
- GB 4053.2-2025固定式金屬梯及平臺(tái)安全要求第2部分:斜梯
- 2026屆上海市長(zhǎng)寧區(qū)市級(jí)名校高一上數(shù)學(xué)期末學(xué)業(yè)質(zhì)量監(jiān)測(cè)模擬試題含解析
- 2026年煙草公司筆試綜合試題及考點(diǎn)實(shí)操指引含答案
- 九年級(jí)寒假期末總結(jié)課件
- 壓鑄機(jī)作業(yè)人員安全培訓(xùn)課件
- 新產(chǎn)品研發(fā)質(zhì)量管控流程詳解
- 我的Python世界(玩Minecraft我的世界學(xué)Python編程)
評(píng)論
0/150
提交評(píng)論