Android 長按電源鍵關機整個流程小學習

來源:互聯網
上載者:User

標籤:android   des   style   blog   class   code   

Android 長按電源鍵關機整個流程小學習

 

           最近研究了一下android關機跟重新啟動功能,看了一些長按電源鍵到彈出關機對話方塊,到真正關機的一系列處理過程。

首先還是來看看這個長按電源鍵都幹了些什麼吧?一般來說,電源鍵都是接到PMU上的,PMU來判斷是長按還短按,當有按鍵訊息產生的時候,系統會有中斷,然後去讀PMU的狀態就可以知道是什麼了。筆者以全志平台的AXP209小議一下,先貼上關鍵代碼:

static int axp_battery_event(struct notifier_block *nb, unsigned long event,        void *data){struct axp_charger *charger =container_of(nb, struct axp_charger, nb);    uint8_t w[9];w[0] = (uint8_t) ((event) & 0xFF);w[1] = POWER20_INTSTS2;w[2] = (uint8_t) ((event >> 8) & 0xFF);w[3] = POWER20_INTSTS3;w[4] = (uint8_t) ((event >> 16) & 0xFF);w[5] = POWER20_INTSTS4;w[6] = (uint8_t) ((event >> 24) & 0xFF);w[7] = POWER20_INTSTS5;w[8] = (uint8_t) (((uint64_t) event >> 32) & 0xFF);if(event & (AXP20_IRQ_BATIN|AXP20_IRQ_BATRE)) {axp_capchange(charger);}if(event & (AXP20_IRQ_ACIN|AXP20_IRQ_USBIN|AXP20_IRQ_ACOV|AXP20_IRQ_USBOV|AXP20_IRQ_CHAOV|AXP20_IRQ_CHAST|AXP20_IRQ_TEMOV|AXP20_IRQ_TEMLO)) {axp_change(charger);}if(event & (AXP20_IRQ_ACRE|AXP20_IRQ_USBRE)) {axp_change(charger);}if(event & AXP20_IRQ_PEKLO) {axp_presslong(charger);}if(event & AXP20_IRQ_PEKSH) {axp_pressshort(charger);}DBG_PSY_MSG("event = 0x%x\n",(int) event);axp_writes(charger->master,POWER20_INTSTS1,9,w);return 0;}

短按跟長按具體也就是上報的延時區別,如下:

static void axp_presslong(struct axp_charger *charger){DBG_PSY_MSG("press long\n");input_report_key(powerkeydev, KEY_POWER, 1);input_sync(powerkeydev);ssleep(2);DBG_PSY_MSG("press long up\n");input_report_key(powerkeydev, KEY_POWER, 0);input_sync(powerkeydev);}static void axp_pressshort(struct axp_charger *charger){DBG_PSY_MSG("press short\n");input_report_key(powerkeydev, KEY_POWER, 1);input_sync(powerkeydev);msleep(100);input_report_key(powerkeydev, KEY_POWER, 0);input_sync(powerkeydev);}

     在inputmanager裡面再解析出是長按還是短按,來做相應處理。如果是長按,就彈出對話方塊,在彈出對話方塊之前,有幾次傳遞,還是activitymanger跟Windowsmanagerservice做宏觀調控,最終把訊息傳到苦逼的ShutdownThread,不過ShutdownThread也不難弄。/*****************************************************************************************************/
聲明:本博內容均由http://blog.csdn.net/sundesheng125原創,轉載請註明出處,謝謝!
/*****************************************************************************************************/

 首先來看一下,在ShutdownThread裡面有一個CloseDialogReceiver來關注Intent.ACTION_CLOSE_SYSTEM_DIALOGS,它收到這個訊息就會關閉這個對話方塊。對話方塊怎麼起來的呢?請看下面的源碼:

 

        if (confirm) {            final CloseDialogReceiver closer = new CloseDialogReceiver(context);            final AlertDialog dialog = new AlertDialog.Builder(context)                    .setTitle(com.android.internal.R.string.power_off)                    .setMessage(resourceId)                    .setPositiveButton(com.android.internal.R.string.yes, new DialogInterface.OnClickListener() {                        public void onClick(DialogInterface dialog, int which) {                            beginShutdownSequence(context);                        }                    })                    .setNegativeButton(com.android.internal.R.string.no, null)                    .create();            closer.dialog = dialog;            dialog.setOnDismissListener(closer);            dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);            dialog.show();        } else {            beginShutdownSequence(context);        }

    其實就是一個AlertDialog,也沒什麼新鮮的,只是在setPositiveButton的時候註冊了clicklistener來監聽你是否按下了,按下了就直接執行beginShutdownSequence。在beginShutdownSequence還會彈出一個進度的對話方塊,代碼如下:

        ProgressDialog pd = new ProgressDialog(context);        pd.setTitle(context.getText(com.android.internal.R.string.power_off));        pd.setMessage(context.getText(com.android.internal.R.string.shutdown_progress));        pd.setIndeterminate(true);        pd.setCancelable(false);        pd.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);        pd.show();

      在裡面還會調用兩個非常重要的Power.shutdown()跟Power.reboot(reason),看你是重啟還是關機了。

    /**     * Low-level function turn the device off immediately, without trying     * to be clean.  Most people should use     * {@link android.internal.app.ShutdownThread} for a clean shutdown.     *     * @deprecated     * @hide     */    @Deprecated    public static native void shutdown();    /**     * Reboot the device.     * @param reason code to pass to the kernel (e.g. "recovery"), or null.     *     * @throws IOException if reboot fails for some reason (eg, lack of     *         permission)     */    public static void reboot(String reason) throws IOException    {        rebootNative(reason);    }    private static native void rebootNative(String reason) throws IOException ;

      再往下跟,

static void android_os_Power_shutdown(JNIEnv *env, jobject clazz){    android_reboot(ANDROID_RB_POWEROFF, 0, 0);}extern int go_recovery(void);static void android_os_Power_reboot(JNIEnv *env, jobject clazz, jstring reason){    if (reason == NULL) {        android_reboot(ANDROID_RB_RESTART, 0, 0);    } else {        const char *chars = env->GetStringUTFChars(reason, NULL);        //android_reboot(ANDROID_RB_RESTART2, 0, (char *) chars);        go_recovery();        android_reboot(ANDROID_RB_RESTART, 0, 0);        env->ReleaseStringUTFChars(reason, chars);  // In case it fails.    }    jniThrowIOException(env, errno);}

 所以,整個流程都是好的,學習理了一下流程,大部分都是源碼,把它搞清楚也是有好處的。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.