关机有几种方式:按键、重启或者其他模式
在关机过程中,主要做了三件事:
1.发送关机广播
2.关闭一些主要服务进程
3.通过PowerManagerService调用底层进行关机
有的模块可能需要监听手机关机事件,所以在关机时发送关机广播,通知相关模块处理。
接下来主要讲解按键响应关机整个流程:
PhoneWindowManager.java | framework\base\services\core\java\com\android\server\policy
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
// Hold a wake lock until the power key is released.
if (!mPowerKeyWakeLock.isHeld()) {
mPowerKeyWakeLock.acquire();
}
......
if (hasLongPressOnPowerBehavior()) {//是否存在长按事件
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);//如果是长按power键就发送MSG_POWER_LONG_PRESS
mHandler.sendMessageDelayed(msg,//发送delay消息, delay 500ms给用户一些时间长按power键显示关机dialog, 同时delay时间也可以通过config.xml中配置
ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
}
......
}
延迟消息最终会在PolicyHandler的handleMessage中处理长按事件。
private class PolicyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
//......
case MSG_POWER_LONG_PRESS:
powerLongPress();//处理长按事件
break;
//........
}
}
}
当按下电源按键的时候会有不同的响应,可能什么都不做,也可能直接关机,没有给用户任何提醒. 或者弹出dialog让用户自己选择. 下面将主要讲解弹出dialog关机的情况。
GlobalActions.java | framework\base\services\core\java\com\android\server\policy
static final int LONG_PRESS_POWER_NOTHING = 0; //长按power键什么都不做
static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1; //为全局动作, 显示关机dialog
static final int LONG_PRESS_POWER_SHUT_OFF = 2; //只有关机一个选项
static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3; //直接关机不用确认
private void powerLongPress() {
final int behavior = getResolvedLongPressOnPowerBehavior();
switch (behavior) {
case LONG_PRESS_POWER_NOTHING://什么都不做,返回
break;
case LONG_PRESS_POWER_GLOBAL_ACTIONS:
mPowerKeyHandled = true;
if (!performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false)) {
performAuditoryFeedbackForAccessibilityIfNeed();
}
showGlobalActionsInternal();//shutDownRing();//显示全局Dailog
break;
case LONG_PRESS_POWER_SHUT_OFF:
case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM://直接关机
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);
break;
}
}
延伸:
可以在调用showGlobalActionsInternal()方法显示全局Dailog之前做一些定制化处理,比如随机播放关机铃声,如shutDownRing()方法:
private void shutDownRing(){
//Merged by lefty.lan @20180803 for shutdown_ring, start
Random random = new Random();
int num = random.nextInt(4)%(4-1+1) + 1;
MediaPlayer mPlayer = new MediaPlayer();
try {
if(mPlayer != null){
switch (num) {
case 1:
mPlayer.setDataSource("/system/media/01.wav");
break;
case 2:
mPlayer.setDataSource("/system/media/02.wav");
break;
case 3:
mPlayer.setDataSource("/system/media/03.wav");
break;
case 4: