Android 长按电源键关机整个流程小学习

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);
}

 所以,整个流程都是好的,学习理了一下流程,大部分都是源码,把它搞清楚也是有好处的。

时间: 2024-08-03 18:24:28

Android 长按电源键关机整个流程小学习的相关文章

Android 长按电源键和短按电源键的详细处理流程

1 Android  Android4.x在Framework的PhoneWindowManager对Power(KeyEvent.KEYCODE_POWER)和Home(KeyEvent.KEYCODE_HOME)键做了处理,不会把这些键传送上层应用程序.如需要把这些键发送给Activity和Service,需要在PhoneWindowManager处理这些键时"发送一个广播出去,然后在应用程序接收到广播后做处理".        如果应用程序只需要获取获取待机.唤醒.关机.网络状态

Android4.x对长按电源键(挂断键)和短按电源键(挂断键)的详细处理流程

1. 简介         Android4.x在Framework的PhoneWindowManager对Power(KeyEvent.KEYCODE_POWER)和Home(KeyEvent.KEYCODE_HOME)键做了处理,不会把这些键传送上层应用程序.如需要把这些键发送给Activity和Service,需要在PhoneWindowManager处理这些键时"发送一个广播出去,然后在应用程序接收到广播后做处理".        如果应用程序只需要获取获取待机.唤醒.关机.网

iPhone6不用快速电源键关机方法

1)打开iPhone6的[设置],选择[辅助功能].(如下图)   2)选择[AssistiveTouch],然后把[AssistiveTouch]选项打开,此时在屏幕上会出现小圆点,点击小圆点.(如下图)   3)在弹出菜单选择[设备],长按[锁定屏幕]即可实现关机.(如下图)   当然了如果是电源键关机的话就更简单了,我们只要长按电源键几秒就会在手机屏幕出现一个滑动按钮关机提醒,我们滑动按钮就可以直接关机了,所有iphone系统或ios设备关机方法都可以使用此方法.

Android实现手电筒电源键关闭功能

在打开手电筒之后 机器休眠 客户要求点击电源键 手电筒需要关闭 frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java @Override public void screenTurnedOn() { synchronized (mLock) { if (mKeyguardDelegate != null) { mKeyguardDelegate.onScreenTurnedOn()

android长按返回键弹出关机框

今天刚好在PhoneWindowManager.java下看,当看到长按Home键的功能时,突然想到是不是可以长按back键来弹出关机框.... 有想法就试试呗.....当然想法是根据长按home键来的,那么我们应该可以模仿长按Home键来做.....经过一番实验,貌似好像可以,拿出来给大家分享一下!!! 先找到PhoneWindowManager.java文件,在framework/base/policy/src/com/....下,在里面我们能找到关机框showGlobalActionsDi

android 添加按电源键结束通话

首先我们发现现在我们所用的android智能手机大部分都有当你在打电话时按power键来挂断电话,一般都是在设置中. 我主要是在原生源码中添加这一功能,主要用于学习....先看一张图:    看到那个按电源键挂断电话吧,那就是我所添加的,本来原生源码中是没有这一栏的..... 大概思路: 首先我先添加这一个checkboxPreference,然后将是否选择这一功能的值(0和1)存到data/data/com.android.providers.settings /databases/setti

android 如何在手机已经按下电源键关闭的情况下打开?

问题描述 android 如何在手机已经按下电源键关闭的情况下打开? 我想通过距离感应器来对手机进行锁屏和解锁,请问有什么好的建议或者方法可以实现? 解决方案 如果手机处于彻底关机的状态,那么你的程序得不到机会执行,没法实现开机.除非是短按下进入待机状态.但是如果驻留你的程序,那么会比较消耗电量,用户体验不好. 只有在操作系统框架下解决了. 解决方案二: 后台service进行唤醒屏幕.

Android利用广播监听按下HOME和电源键

MainActivity如下: package cc.testhome; import cc.testhome.HomeKeyObserver.OnHomeKeyListener; import cc.testhome.PowerKeyObserver.OnPowerKeyListener; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * 利用广播监听Home键的按下和长按Home键 * 利用广播监听电

Android实现长按back键退出应用程序的方法

  本文实例讲述了Android实现长按back键退出应用程序的方法.分享给大家供大家参考.具体分析如下: 最近在做一个Android上的应用,碰到一个问题就是如何实现长按back键退出应用程序.在网上查找了很多资料,发现几乎没有这样的实现,大部分在处理时是双击back键来退出应用程序.参考了一下双击back键退出应用程序的代码,网上主流的一种方法是下面这种方法,实现起来比较简单: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Override