电源键 + 音量上键 长按实现关机功能 Android 9.0
主要涉及修改的文件是
/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
其中 interceptKeyBeforeQueueing 对按键事件进行拦截处理
1 组合键关机实现
1.1 添加必要参数
//控制组合键的间隔时长
private static final long COMBINATION_KEY_SHUTDOWN__DELAY_MILLIS = 1000;
private boolean mShutDownChordVolumeUpKeyTriggered;
private long mShutDownChordVolumeUpKeyTime;
private boolean mShutDownChordVolumeUpKeyConsumed;
private boolean mShutDownChordPowerKeyTriggered;
private long mShutDownChordPowerKeyTime;
//定义延时发送的信息
private static final int MSG_POWER_VOLUME_COMBINATION_PRESS = 31;
1.1 添加 handler 信息
case MSG_POWER_VOLUME_COMBINATION_PRESS:
if (mShutDownChordPowerKeyTriggered && mShutDownChordVolumeUpKeyTriggered) {
// Intent intent1 = new Intent("android.intent.action.MAIN");
// intent1.setClassName("com.android.factorytest","com.android.factorytest.framework.FactoryTestActivity");
// intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// mContext.startActivity(intent1);
mPowerKeyHandled = true;
performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
mWindowManagerFuncs.shutdown(false);
}
break;
1.3 电源键 DOWN处理
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
+ mShutDownChordPowerKeyTriggered = true;
+ mShutDownChordPowerKeyTime = event.getDownTime();
1.4 电源键 UP 处理
private void interceptPowerKeyUp(KeyEvent event, boolean interactive, boolean canceled) {
final boolean handled = canceled || mPowerKeyHandled;
mScreenshotChordPowerKeyTriggered = false;
+ mShutDownChordPowerKeyTriggered = false;
cancelPendingScreenshotChordAction();
cancelPendingPowerKeyAction();
+ cancelPendingShutDownChordAction();
1.5 interceptCombinationShutdownChord 方法实现
+ private void interceptCombinationShutdownChord() {
+ if (mShutDownChordPowerKeyTriggered && mShutDownChordVolumeUpKeyTriggered && !mScreenshotChordVolumeDownKeyTriggered) {
+ final long now = SystemClock.uptimeMillis();
+ if (now <= mShutDownChordVolumeUpKeyTime + COMBINATION_KEY_SHUTDOWN__DELAY_MILLIS
+ && now <= mShutDownChordPowerKeyTime
+ + COMBINATION_KEY_SHUTDOWN__DELAY_MILLIS) {
+ mShutDownChordVolumeUpKeyConsumed = true;
+ cancelPendingPowerKeyAction();
+ Message msg = mHandler.obtainMessage(MSG_POWER_VOLUME_COMBINATION_PRESS);
+ mHandler.sendMessageDelayed(msg,5000);
+ }
+ }
+ }
+
1.6 cancelPendingShutDownChordAction
+ private void cancelPendingShutDownChordAction() {
//从队列中移除
+ mHandler.removeMessages(MSG_POWER_VOLUME_COMBINATION_PRESS);
+ }
+
1.7 interceptKeyBeforeDispatching
@Override
public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
...
+ if ((flags & KeyEvent.FLAG_FALLBACK) == 0) {
+ if (mShutDownChordVolumeUpKeyTriggered && !mShutDownChordPowerKeyTriggered) {
+ final long now = SystemClock.uptimeMillis();
+ final long timeoutTime = mShutDownChordVolumeUpKeyTime
+ + COMBINATION_KEY_SHUTDOWN__DELAY_MILLIS;
+ if (now <timeoutTime) {
+ return timeoutTime - now;
+ }
+ }
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && mShutDownChordVolumeUpKeyConsumed) {
+ if (!down) {
+ mShutDownChordVolumeUpKeyConsumed = false;
+ }
+ return -1;
+ }
+ }
+
1.8 音量上键 DOWN/UP 处理
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
...
...
interceptAccessibilityShortcutChord();
interceptRingerToggleChord();
}
+ mShutDownChordVolumeUpKeyTime = event.getDownTime();
+ mShutDownChordVolumeUpKeyTriggered = true;
+ mShutDownChordVolumeUpKeyConsumed = false;
+ interceptCombinationShutdownChord();
} else {
mA11yShortcutChordVolumeUpKeyTriggered = false;
+ mShutDownChordVolumeUpKeyTriggered = false;
cancelPendingScreenshotChordAction();
cancelPendingAccessibilityShortcutAction();
cancelPendingRingerToggleChordAction();
+ cancelPendingShutDownChordAction();
}
}