安卓源代碼修改之framework下面長按power鍵,修改安卓原生的關機、重啓界面(一)

前幾天工作中遇到一個問題,修改安卓源代碼中的長按Power鍵之後彈出的界面,以及點擊事件。下面給大家說一下我自己的一些心得。
我的需求是這樣的,仿造華爲手機,長按power之後出來一個Activity,然後四個圖片,省電模式、情景模式、重啓、關機。點擊重啓或關機按鈕,其他三個按鈕就會漸變的往後移動,直至消失,然後點擊的按鈕自己移動到中間。然後點擊一下除了按鈕之外的任何一個地方就要返回到上一級菜單。點擊一下情景模式,其他三個按鈕也會漸變消失,然後跳出一個dialog,讓用戶選擇響鈴、震動、靜音。

剛開始,接到這個任務的時候,根本就沒有想到過,自己能去改源代碼。。但是上面給我限制了時間,讓我必須得完成,所以就一股腦的認真對待這個任務了。其實修改源代碼,改成自己想要的需求,只要認真做,真的一點也不難,不要總覺得自己沒有涉及過源代碼,覺得自己做不來啥的,你又沒有嘗試着去做,你怎麼知道自己不行?是吧,所以下面我回歸正題上!
主要修改代碼的路徑是frameworks\base\services\core\java\com\android\server\policy中的GlobalActions.java。
現在我們從頭看一下長按power鍵的那個操作在哪裏。frameworks\base\services\core\java\com\android\server\policy中的PhoneWindowManager這個類中有一個方法叫showGlobalActionsInternal()。只要長按power鍵就係統就會調用這個方法。代碼不多,如下:
void showGlobalActionsInternal() {
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
if (mGlobalActions == null) {
mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);
}
final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();
mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());
if (keyguardShowing) {
// since it took two seconds of long press to bring this up,
// poke the wake lock so they have some time to see the dialog.
mPowerManager.userActivity(SystemClock.uptimeMillis(), false);
}
}
好好看一下這段代碼,就會知道,最終調用的是GlobalActions這個類,因爲他new了一個GlobalActions類。(接下來就是無限的調用了,A方法調用B方法,B方法調用C方法,C方法調用D方法。。。。最終調用出了我們想要出來的界面。耐心一點就好了!)
然後我們看到了一句最重要的代碼— mGlobalActions.showDialog,我們再跳轉到GlobalActions類,找一下 showDialog這個方法。
public void showDialog(boolean keyguardShowing, boolean isDeviceProvisioned) {
mKeyguardShowing = keyguardShowing;
mDeviceProvisioned = isDeviceProvisioned;
if (mDialog != null) {
mDialog.dismiss();
mDialog = null;
// Show delayed, so that the dismiss of the previous dialog completes
mHandler.sendEmptyMessage(MESSAGE_SHOW);
} else {
handleShow();
}
}
這段代碼中我們看到了handleShow();這個方法,那我們就再跳轉到handleShow();這個方法看一下,然後我們看到createDialog();這個最終調用的方法。好好看完這個方法之後發現,原先長按power之後跳出來的Dialog,其實不是我們想象的那麼建的的一個對話框,說白點就是,他不是Dialog,他是ListView,然後適配器填充了所有的數據之後顯示在這個ListView上,讓我們第一眼看的時候誤以爲是Dialog。。然後這個ListView是怎麼顯示的呢?這裏他又new了一個新的類,GlobalActionsDialog,他是繼承於Dialog的,但是這個太複雜了,說實話,我也沒搞明白爲什麼要寫的這麼複雜。。。
好,廢話少說,現在我們整體看一下,長按power鍵之後系統走的流程。phoneWindowManager–>showGlobalActionsInternal()—>showDialog()—>這時已經跑到GlobalActions.java中去了—>handleShow()—>createDialog()—>GlobalActionsDialog()。因爲GlobalActionsDialog()太複雜,我不可能會把他改來改去然後改成我自己想要的,要是去改這個,給我一個月的時間我都不一定能做得來,所以我索性,把handleShow()這個方法中的所有代碼都註釋掉了,代碼不多,不會影響其他,當然createDialog()就不會再被我調用了,然後我在handleShow()這個方法裏重新startActivity了一個新的Activity。也就是說長按power鍵之後,就會startActivity,然後跳轉到新的Activity上。然後這個Activity的佈局,就不用我多說了吧,自己在eclipse上寫好直接複製進去frameworks\base\core\res\res\layout這個路徑下面就ok了。
下面是我在handleShow()這個方法中,把原先的註釋掉之後,自己寫的幾行代碼:
private void handleShow() {
Intent intent=new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setClass(mContext, Dialog_Activity2.class);
mContext.startActivity(intent);
}
把這幾行代碼一寫,長按power鍵之後就會跳出一個Activity,上面顯示的就是你自己寫好的佈局。當然,在這個成功出現之前,當然會報很多錯誤。所有報過的錯誤以及修改方法都列在下面:
1、把你自己寫好的Activity,這裏就是Dialog_Activity2了,把這個Activity放到指定的目錄下,frameworks\base\services\core\java\com\android\server。
2、在AndroidManifest.xml文件中(frameworks\base\core\res路徑下)定義你這個Activity。
activity android:name=”com.android.server.Dialog_Activity2”
android:taskAffinity=”com.xjp”
android:theme=”@style/Transparent”
Activity放到了哪裏,就在這個文件中也要寫好他的路徑,不然也會報錯,說找不到對應的Activity!!!
3、在上面的handleShow()方法中的intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)這一行以及2標題中的 android:taskAffinity=”com.xjp”這一行代碼,這兩行代碼是必須要寫進去的。不然就會編譯不過,報錯的大概意思就是說,“你startActivity跳轉的時候,你當前的頁面不是Activity,你必須給他設置屬性這樣才能跳轉,intent需要setFlags”,至於這兩行代碼是啥意思,搞安卓的人大概都能明白,Activity的啓動方式有四種,我寫的這個NEW_TASK就是其中的一種(不懂得可以多查查資料),總之這兩行是必須要加的!
4、然後framework有一個很獨特的地方,你給他加了一個佈局對不對,就是你自己寫的那個佈局,然後放進layout文件夾中的那個xml 。記住的一點就是必須給frameworks\base\core\res\res\values中的symbol.xml中給他定義,不然也是會報錯的。以及你在你的這個佈局中定義的所有的id、drawable、string等等都在這個文件中定義。例如:
< java-symbol type=”id” name=”textView4”
java-symbol type=”id” name=”imageButton1”
java-symbol type=”color” name=”transparent_background”
java-symbol type=”style” name=”Transparent”
java-symbol type=”layout” name=”long_press_activity”
java-symbol type=”anim” name=”single1”
java-symbol type=”drawable” name=”qingjing”
java-symbol type=”string” name=”shengdian”
眼尖的同學也看到了吧,color、style這種的也要定義的!!!!
5、因爲這個需求還有漸變,移動,消失這些動畫效果,所以在frameworks\base\core\res\res中的anim文件中,把自己所有的動畫的XML文件也是要放進去的!

以上只是長按power鍵之後,正確的顯示你自己寫好的佈局,不會讓他報錯。至於裏面的四個按鈕的點擊事件,後期再發布!!

以上都是本人按照自己做出來的效果寫出來的心得,希望能幫助到有需要的童鞋~~如有雷同純屬巧合!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章