通过查看 PhoneWindowManager 中 power 相关流程,发现Android 原生code中已经添加了对Power键连按的接口,目前可以定义按一次、按两次及按三次时对应的响应操作。
Android中对Power键连按次数的定义如下:
frameworks\base\core\res\res\values\config.xml
- 短按一次power键系统定义:
<!-- Control the behavior when the user short presses the power button.
0 - Nothing
1 - Go to sleep (doze)
2 - Really go to sleep (don't doze)
3 - Really go to sleep and go home (don't doze)
4 - Go to home
5 - Dismiss IME if shown. Otherwise go to home
-->
<integer name="config_shortPressOnPowerBehavior">1</integer>
- 连续短按两次power键系统定义:
<!-- Control the behavior when the user double presses the power button.
0 - Nothing
1 - Toggle theater mode setting
2 - Brightness boost
-->
<integer name="config_doublePressOnPowerBehavior">0</integer>
- 连续短按三次power键系统定义:
<!-- Control the behavior when the user triple presses the power button.
0 - Nothing
1 - Toggle theater mode setting
2 - Brightness boost
-->
<integer name="config_triplePressOnPowerBehavior">0</integer>
可以看到短按两次和短按三次都是定义的 0,对应为 nothing,即不做任何操作。
power键在config中的定义,最终是在PhoneWindowManager.java 的 powerPress()方法中判断和实现。
frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java
private void powerPress(long eventTime, boolean interactive, int count) {
if (mScreenOnEarly && !mScreenOnFully) {
Slog.i(TAG, "Suppressed redundant power key press while "
+ "already in the process of turning the screen on.");
return;
}
if (count == 2) {//短按两次power键的实现
powerMultiPressAction(eventTime, interactive, mDoublePressOnPowerBehavior);
} else if (count == 3) {{//短按三次power键的实现
powerMultiPressAction(eventTime, interactive, mTriplePressOnPowerBehavior);
} else if (interactive && !mBeganFromNonInteractive) {
switch (mShortPressOnPowerBehavior) {
case SHORT_PRESS_POWER_NOTHING:
break;
case SHORT_PRESS_POWER_GO_TO_SLEEP:
goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP:
goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
break;
case SHORT_PRESS_POWER_REALLY_GO_TO_SLEEP_AND_GO_HOME:
goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON,
PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE);
launchHomeFromHotKey();
break;
case SHORT_PRESS_POWER_GO_HOME:
shortPressPowerGoHome();
break;
case SHORT_PRESS_POWER_CLOSE_IME_OR_GO_HOME: {
if (mDismissImeOnBackKeyPressed) {
if (mInputMethodManagerInternal == null) {
mInputMethodManagerInternal =
LocalServices.getService(InputMethodManagerInternal.class);
}
if (mInputMethodManagerInternal != null) {
mInputMethodManagerInternal.hideCurrentInputMethod();
}
} else {
shortPressPowerGoHome();
}
break;
}
}
}
}
由code中发现,短按两次,三次都是在powerMultiPressAction()中实现
private void powerMultiPressAction(long eventTime, boolean interactive, int behavior) {
switch (behavior) {
case MULTI_PRESS_POWER_NOTHING:
break;
case MULTI_PRESS_POWER_THEATER_MODE:
if (!isUserSetupComplete()) {
Slog.i(TAG, "Ignoring toggling theater mode - device not setup.");
break;
}
if (isTheaterModeEnabled()) {
Slog.i(TAG, "Toggling theater mode off.");
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 0);
if (!interactive) {
wakeUpFromPowerKey(eventTime);
}
} else {
Slog.i(TAG, "Toggling theater mode on.");
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.THEATER_MODE_ON, 1);
if (mGoToSleepOnButtonPressTheaterMode && interactive) {
goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, 0);
}
}
break;
case MULTI_PRESS_POWER_BRIGHTNESS_BOOST:
Slog.i(TAG, "Starting brightness boost.");
if (!interactive) {
wakeUpFromPowerKey(eventTime);
}
mPowerManager.boostScreenBrightness(eventTime);
break;
}
}
正好就是config_doublePressOnPowerBehavior和config_triplePressOnPowerBehavior对应的三种状态,因此,可以以此为入口,通过自定义第四种状态,来实现自定义功能,比如:紧急呼叫功能。
附上同事所实现的连续短按三次power键实现紧急呼叫功能:
1) 自定义状态值
Config.xml
<integer name="config_triplePressOnPowerBehavior">3</integer>
PhoneWindowManager.java
static final int MULTI_PRESS_POWER_EMERGENCY_CALL = 3;
2) 实现对应功能
PhoneWindowManager.java 的 powerMultiPressAction()方法添加 case:
case MULTI_PRESS_POWER_EMERGENCY_CALL:
Intent callIntent = new Intent(Intent.ACTION_CALL_EMERGENCY);
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
callIntent.setData(Uri.parse("tel:112"));
mContext.startActivity(callIntent);
break;