為Android系統定製重啟功能

來源:互聯網
上載者:User
按計劃每周更新一篇技術博文,第二篇:《為Android系統定製重啟功能》
一、Android系統重啟的實現方式 1、廣播方式之前的博文介紹過這種方式《使用廣播實現的Android關機及重啟》,注意應用要在源碼中編譯,並且應用需要系統許可權。
2、通過init.rc啟動系統服務來運行sh檔案 a.重啟shell檔案(system_reboot.sh),放在system/etc/目錄下
#!/system/bin/sh  reboot

b.init.rc中加入一個Service的定義

   service system_reboot /system/etc/system_reboot.sh     oneshot     disabled

c.啟動系統服務

SystemProperties.set("ctl.start", "system_reboot");
3、直接代碼中執行命令列需要取得root許可權
Process proc = Runtime.getRuntime().exec(cmd);

    以上三種方法可以實現重啟,但現在需要實現長按關機鍵提示對話方塊中有重啟選項,這就設計修改系統源碼,感覺修改源碼,是個很難的工作,其實找到關機提示框的代碼位置,一切都變得很簡單。
二、修改源碼定製重啟功能1、跟蹤長按Power鍵相關代碼    首先要瞭解長按電源鍵彈出對話方塊的相關源碼位置,通過跟蹤找到PhoneWindowManager.java中有截斷長按電源鍵的方法,繼續跟蹤代碼找到Runnable mPowerLongPress =
new Runnable(),在該runnable裡邊調用showGlobalActionsDialog()方法便是顯示長按power鍵彈出的關機提示對話方塊,如果你的機器是原生態的,預設提示“飛航模式”,“靜音”和“關機”選項。     showGlobalActionsDialog建立關機對話方塊的代碼在GlobalActions.java裡邊,主要代碼如下: 

private AlertDialog createDialog() {……mItems = new ArrayList<Action>();        // first: power off        mItems.add(            new SinglePressAction(                    com.android.internal.R.drawable.ic_lock_power_off,                    R.string.global_action_power_off) {                public void onPress() {                    // shutdown by making sure radio and power are handled accordingly.                    ShutdownThread.shutdown(mContext, true);                }                public boolean showDuringKeyguard() {                    return true;                }                public boolean showBeforeProvisioning() {                    return true;                }            });        // next: airplane mode        mItems.add(mAirplaneModeOn);        // last: silent mode        if (SHOW_SILENT_TOGGLE) {            mItems.add(mSilentModeAction);        }……}


2、重啟方法    跟蹤源碼到此處,需要加入重啟部分的源碼也是往AlertDialog 添加多一項,顯示部分的代碼直接造這power
off即可,需要加入重啟邏輯的代碼直接修改回調方法onPress裡邊(上邊代碼粗體部分),一開始,我嘗試了前文中提示的三種方法中的方法一和方法三均行不通,後來也沒再進一步排查原因,估計許可權問題。    本打算使用方法二再嘗試一下,突然想到為何不去看看關機的邏輯代碼ShutdownThread.shutdown(),開啟ShutdownThread.java,很快就發現源碼裡邊也有reboot的實現方法,如下:    

/**     * Request a clean shutdown, waiting for subsystems to clean up their     * state etc.  Must be called from a Looper thread in which its UI     * is shown.     *     * @param context Context used to display the shutdown progress dialog.     * @param reason code to pass to the kernel (e.g. "recovery"), or null.     * @param confirm true if user confirmation is needed before shutting down.     */    public static void reboot(final Context context, String reason, boolean confirm){     ……     }

   該方法的使用直接看注釋知道,reboot方法的後兩個參數解釋如下:     reason  如果值為是null,正常重啟;如果是recovery,系統重啟進入recovery
mode     confirm
true顯示關機提示框,需要使用者【確認】;false不顯示提示框,直接關機 3、代碼修改a.在關機提示框中加入重啟選項    弄清楚關機相關的源碼,直接在GlobalActions.java的createDialog方法中加入如下代碼即可: 

      ... // next: reboot global_action_reboot        mItems.add(         new SinglePressAction(                    com.android.internal.R.drawable.ic_lock_power_off,                    R.string.global_action_reboot) {                public void onPress() {              // reboot                 ShutdownThread.reboot(mContext,null,false);                              }                public boolean showDuringKeyguard() {                    return true;                }                public boolean showBeforeProvisioning() {                    return true;                }            });...

b.修改重啟提示框,以區分關機提示框  因為提示框預設是“關機”,在ShutdownThread.java的beginShutdownSequence(context)方法中代碼修改如下:

/*///修改前:…… pd.setTitle(context.getText(com.android.internal.R.string.power_off)); pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));……/*///修改後:……if(mReboot){     // reboot progress         pd.setTitle(context.getText(com.android.internal.R.string.global_action_reboot));         pd.setMessage(context.getText(com.android.internal.R.string.reboot_progress));     }else{          // shutdown progress         pd.setTitle(context.getText(com.android.internal.R.string.power_off));         pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));     }……//*/
     重啟功能實現了,但是不能到此結束,定製Android系統的重啟功能,添加選項和修改重啟提示框時加入了“重啟”和“正在重啟”的字串,所以會涉及到在系統資源檔中添加新的字串,源碼中資源檔涉及到的多國語言直接忽略,我只在values/strings.xml和values-zh-rCN/strings.xml兩個檔案中加入對應的字串:
    <string name="global_action_reboot">重啟</string>    <string name="reboot_progress">"正在重啟..."</string>
c.最後編譯因為修改涉及到系統資源檔又涉及到policy.jar包,經過多次嘗試,正確的編譯順序如下:步驟1.編譯frameworks/base/res,在out/target/product/X裝置名稱X/system/framework/目錄下產生framework-res.apk步驟2.編譯frameworks/base/,在o同樣目錄下產生framework.jar包(不能忽略,不然步驟3編譯報錯)步驟3.編譯frameworks/base/policy,在同樣目錄下產生policy.jar包

附錄:本例源碼以Android 4.0.4為準(2.3一樣),關機相關的源碼路徑:ics/frameworks/base/policy/src/com/android/internal/policy/impl/目錄下:PhoneWindowManager.javaGlobalActions.java
ics/frameworks/base/core/java/com/android/internal/app/目錄下:ShutdownThread.java

PS:4.1.1 關機相關方法位置有些變化源碼已經把關機的介面整合到:public class
WindowManagerService extends IWindowManager.Stub
        implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs{...}中不過可以直接使用:import com.android.server.pm.ShutdownThread;

ShutdownThread.shutdown(mContext, true);
ShutdownThread.rebootSafeMode(mContext, true);

檔案路徑:Android4.1.1/jb/frameworks/base/services/java/com/android/server/pm/
ShutdownThread.java

Android4.1.1/jb/frameworks/base/services/java/com/android/server/wm
WindowManagerService.java

...
參考引用:1、Android應用程式獲得root許可權
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.