【移動(dòng)應(yīng)用開發(fā)技術(shù)】android HOME點(diǎn)擊事件的獲取_第1頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android HOME點(diǎn)擊事件的獲取_第2頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android HOME點(diǎn)擊事件的獲取_第3頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android HOME點(diǎn)擊事件的獲取_第4頁(yè)
【移動(dòng)應(yīng)用開發(fā)技術(shù)】android HOME點(diǎn)擊事件的獲取_第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余2頁(yè)可下載查看

付費(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論