Android 长按电源键弹出的GlobalActions菜单

news/2025/1/12 13:48:00/

长按事件动作的配置

frameworks\base\core\res\res\values\config.xml     选择1会弹出Global actions menu

<!-- Control the behavior when the user long presses the power button.0 - Nothing1 - Global actions menu2 - Power off (with confirmation)3 - Power off (without confirmation)4 - Go to voice assist5 - Go to assistant (Settings.Secure.ASSISTANT)--><integer name="config_longPressOnPowerBehavior">1</integer>

frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager.java

对长按事件的处理

    private void powerLongPress(long eventTime) {final int behavior = getResolvedLongPressOnPowerBehavior();Slog.d(TAG, "powerLongPress: eventTime=" + eventTime+ " mLongPressOnPowerBehavior=" + mLongPressOnPowerBehavior);switch (behavior) {case LONG_PRESS_POWER_NOTHING:break;case LONG_PRESS_POWER_GLOBAL_ACTIONS:mPowerKeyHandled = true;performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,"Power - Long Press - Global Actions");showGlobalActions();break;case LONG_PRESS_POWER_SHUT_OFF:case LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM:mPowerKeyHandled = true;performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,"Power - Long Press - Shut Off");sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);mWindowManagerFuncs.shutdown(behavior == LONG_PRESS_POWER_SHUT_OFF);break;case LONG_PRESS_POWER_GO_TO_VOICE_ASSIST:mPowerKeyHandled = true;performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, false,"Power - Long Press - Go To Voice Assist");// Some devices allow the voice assistant intent during setup (and use that intent// to launch something else, like Settings). So we explicitly allow that via the// config_allowStartActivityForLongPressOnPowerInSetup resource in config.xml.launchVoiceAssist(mAllowStartActivityForLongPressOnPowerDuringSetup);break;case LONG_PRESS_POWER_ASSISTANT:mPowerKeyHandled = true;performHapticFeedback(HapticFeedbackConstants.ASSISTANT_BUTTON, false,"Power - Long Press - Go To Assistant");final int powerKeyDeviceId = Integer.MIN_VALUE;launchAssistAction(null, powerKeyDeviceId, eventTime,AssistUtils.INVOCATION_TYPE_POWER_BUTTON_LONG_PRESS);break;}}
@Overridepublic void showGlobalActions() {mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);}
public void handleMessage(Message msg) {switch (msg.what) {case MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK:dispatchMediaKeyWithWakeLock((KeyEvent)msg.obj);break;case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);break;case MSG_DISPATCH_SHOW_RECENTS:showRecentApps(false);break;case MSG_DISPATCH_SHOW_GLOBAL_ACTIONS:showGlobalActionsInternal();break;
void showGlobalActionsInternal() {if (mGlobalActions == null) {mGlobalActions = new GlobalActions(mContext, mWindowManagerFuncs);}final boolean keyguardShowing = isKeyguardShowingAndNotOccluded();mGlobalActions.showDialog(keyguardShowing, isDeviceProvisioned());// since it took two seconds of long press to bring this up,// poke the wake lock so they have some time to see the dialog.mPowerManager.userActivity(SystemClock.uptimeMillis(), false);}

frameworks\base\services\core\java\com\android\server\policy\GlobalActions.java

private void ensureLegacyCreated() {if (mLegacyGlobalActions != null) return;mLegacyGlobalActions = new LegacyGlobalActions(mContext, mWindowManagerFuncs,this::onGlobalActionsDismissed);}public void showDialog(boolean keyguardShowing, boolean deviceProvisioned) {if (DEBUG) Slog.d(TAG, "showDialog " + keyguardShowing + " " + deviceProvisioned);if (mGlobalActionsProvider != null && mGlobalActionsProvider.isGlobalActionsDisabled()) {return;}mKeyguardShowing = keyguardShowing;mDeviceProvisioned = deviceProvisioned;mShowing = true;if (mGlobalActionsAvailable && !"box".equals(SystemProperties.get("ro.target.product","unkonw"))) {mHandler.postDelayed(mShowTimeout, 5000);mGlobalActionsProvider.showGlobalActions();} else {// SysUI isn't alive, show legacy menu.ensureLegacyCreated();mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned);}}

 item的创建在LegacyGlobalActions里

frameworks\base\services\core\java\com\android\server\policy\LegacyGlobalActions.java

/*** Create the global actions dialog.* @return A new dialog.*/private ActionsDialog createDialog() {// Simple toggle style if there's no vibrator, otherwise use a tri-stateif (!mHasVibrator) {mSilentModeAction = new SilentModeToggleAction();} else {mSilentModeAction = new SilentModeTriStateAction(mContext, mAudioManager, mHandler);}mAirplaneModeOn = new ToggleAction(R.drawable.ic_lock_airplane_mode,R.drawable.ic_lock_airplane_mode_off,R.string.global_actions_toggle_airplane_mode,R.string.global_actions_airplane_mode_on_status,R.string.global_actions_airplane_mode_off_status) {@Overridepublic void onToggle(boolean on) {if (mHasTelephony && TelephonyProperties.in_ecm_mode().orElse(false)) {mIsWaitingForEcmExit = true;// Launch ECM exit dialogIntent ecmDialogIntent =new Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null);ecmDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);mContext.startActivity(ecmDialogIntent);} else {changeAirplaneModeSystemSetting(on);}}@Overrideprotected void changeStateFromPress(boolean buttonOn) {if (!mHasTelephony) return;// In ECM mode airplane state cannot be changedif (!TelephonyProperties.in_ecm_mode().orElse(false)) {mState = buttonOn ? State.TurningOn : State.TurningOff;mAirplaneState = mState;}}@Overridepublic boolean showDuringKeyguard() {return true;}@Overridepublic boolean showBeforeProvisioning() {return false;}};onAirplaneModeChanged();mItems = new ArrayList<Action>();String[] defaultActions = mContext.getResources().getStringArray(com.android.internal.R.array.config_globalActionsList);ArraySet<String> addedKeys = new ArraySet<String>();for (int i = 0; i < defaultActions.length; i++) {String actionKey = defaultActions[i];if (addedKeys.contains(actionKey)) {// If we already have added this, don't add it again.continue;}if (GLOBAL_ACTION_KEY_POWER.equals(actionKey)) {mItems.add(new PowerAction(mContext, mWindowManagerFuncs));} else if (GLOBAL_ACTION_KEY_AIRPLANE.equals(actionKey)) {mItems.add(mAirplaneModeOn);} else if (GLOBAL_ACTION_KEY_BUGREPORT.equals(actionKey)) {if (Settings.Global.getInt(mContext.getContentResolver(),Settings.Global.BUGREPORT_IN_POWER_MENU, 0) != 0 && isCurrentUserOwner()) {mItems.add(new BugReportAction());}} else if (GLOBAL_ACTION_KEY_SILENT.equals(actionKey)) {if (mShowSilentToggle) {mItems.add(mSilentModeAction);}} else if (GLOBAL_ACTION_KEY_USERS.equals(actionKey)) {if (SystemProperties.getBoolean("fw.power_user_switcher", false)) {addUsersToMenu(mItems);}} else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) {mItems.add(getSettingsAction());} else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {mItems.add(getLockdownAction());} else if (GLOBAL_ACTION_KEY_VOICEASSIST.equals(actionKey)) {mItems.add(getVoiceAssistAction());} else if (GLOBAL_ACTION_KEY_ASSIST.equals(actionKey)) {mItems.add(getAssistAction());} else if (GLOBAL_ACTION_KEY_RESTART.equals(actionKey)) {mItems.add(new RestartAction(mContext, mWindowManagerFuncs));} else {Log.e(TAG, "Invalid global action key " + actionKey);}// Add here so we don't add more than one.addedKeys.add(actionKey);}if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {mItems.add(getEmergencyAction());}mAdapter = new ActionsAdapter(mContext, mItems,() -> mDeviceProvisioned, () -> mKeyguardShowing);AlertController.AlertParams params = new AlertController.AlertParams(mContext);params.mAdapter = mAdapter;params.mOnClickListener = this;params.mForceInverseBackground = true;ActionsDialog dialog = new ActionsDialog(mContext, params);dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.dialog.getListView().setItemsCanFocus(true);dialog.getListView().setLongClickable(true);dialog.getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {@Overridepublic boolean onItemLongClick(AdapterView<?> parent, View view, int position,long id) {final Action action = mAdapter.getItem(position);if (action instanceof LongPressAction) {return ((LongPressAction) action).onLongPress();}return false;}});dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);// Don't acquire soft keyboard focus, to avoid destroying state when capturing bugreportsdialog.getWindow().setFlags(FLAG_ALT_FOCUSABLE_IM, FLAG_ALT_FOCUSABLE_IM);dialog.setOnDismissListener(this);return dialog;}private class BugReportAction extends SinglePressAction implements LongPressAction {public BugReportAction() {super(com.android.internal.R.drawable.ic_lock_bugreport, R.string.bugreport_title);}@Overridepublic void onPress() {// don't actually trigger the bugreport if we are running stability// tests via monkeyif (ActivityManager.isUserAMonkey()) {return;}// Add a little delay before executing, to give the// dialog a chance to go away before it takes a// screenshot.mHandler.postDelayed(new Runnable() {@Overridepublic void run() {try {// Take an "interactive" bugreport.MetricsLogger.action(mContext,MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_INTERACTIVE);ActivityManager.getService().requestInteractiveBugReport();} catch (RemoteException e) {}}}, 500);}@Overridepublic boolean onLongPress() {// don't actually trigger the bugreport if we are running stability// tests via monkeyif (ActivityManager.isUserAMonkey()) {return false;}try {// Take a "full" bugreport.MetricsLogger.action(mContext, MetricsEvent.ACTION_BUGREPORT_FROM_POWER_MENU_FULL);ActivityManager.getService().requestFullBugReport();} catch (RemoteException e) {}return false;}@Overridepublic boolean showDuringKeyguard() {return true;}@Overridepublic boolean showBeforeProvisioning() {return false;}@Overridepublic String getStatus() {return mContext.getString(com.android.internal.R.string.bugreport_status,Build.VERSION.RELEASE_OR_CODENAME,Build.ID);}}

添加菜单可以参考 Android 6.0长按电源键添加重启菜单-CSDN博客


http://www.ppmy.cn/news/1270807.html

相关文章

中华鲲鹏 深耕湾区 华鲲振宇重磅亮相第二届数字政府建设峰会

12月8日,由国家互联网信息办公室指导,广东省人民政府、香港特别行政区政府、澳门特别行政区政府联合主办的第二届数字政府建设峰会暨“数字湾区”发展论坛在广州开幕。第十二届全国政协副主席、国家电子政务专家委员会主任王钦敏,中央宣传部副部长、中央网信办主任、国家网信办…

数据分析为何要学统计学(11)——如何进行时间序列分析

时间序列是由随时间变化的值构成&#xff0c;如产品销量、气温数据等等&#xff0c;该数据集合是个有序序列&#xff0c;除了数值&#xff0c;没有其他因素。通过对时间序列展开分析&#xff0c;能够回答如下问题&#xff1a; &#xff08;1&#xff09;被研究对象的活动特征是…

find命令中的-exec选项

-exec 选项通常用于在 find 命令的结果集上执行特定的命令。以下是一些使用 -exec 的示例&#xff1a; 查找并删除文件&#xff1a; find /path/to/files -type f -name "*.bak" -exec rm {} \;这个命令查找 /path/to/files 目录及其子目录中所有以 “.bak” 结尾的文…

金和 OA C6/Control/GetSqlData.aspx/.ashx SQL 注入漏洞复现

0x01 产品简介 金和网络是专业信息化服务商,为城市监管部门提供了互联网+监管解决方案,为企事业单位提供组织协同OA系统开发平台,电子政务一体化平台,智慧电商平台等服务。 0x02 漏洞概述 金和 OA C6/Control/GetSqlData.aspx/.ashx接口处存在SQL注入漏洞,攻击者除了可以利…

毅速:金属3D打印引领制造业进入新时代

随着科技的飞速发展&#xff0c;3D打印技术逐渐渗透到各个领域&#xff0c;为制造业带来了革命性的变革。其中&#xff0c;金属3D打印技术以其独特的优势&#xff0c;正逐渐成为制造业的新宠。 金属3D打印&#xff0c;也称为金属粉末烧结&#xff0c;是一种利用高能激光束将金属…

Python入门第3篇(异常处理、dotenv)

目录 异常处理 dotenv 异常处理 Python同样存在异常处理&#xff0c;基本处理逻辑和其他开发语言差不多&#xff0c;具体语法上有一些差异 def chufa(a:int,b:int)->int:try:# 针对如下逻辑进行try语句ca/bprint(c)except ZeroDivisionError:# 如果是被0除的异常&#x…

最简单的基于 FFmpeg 的音频解码器

最简单的基于 FFmpeg 的音频解码器 最简单的基于 FFmpeg 的音频解码器正文参考工程文件下载 参考雷霄骅博士的文章&#xff0c;链接&#xff1a;最简单的基于FFMPEGSDL的音频播放器&#xff1a;拆分-解码器和播放器 最简单的基于 FFmpeg 的音频解码器 正文 FFmpeg 音频解码器…

第16节:Vue3 响应式对象reactive()

在UniApp中使用Vue3框架时&#xff0c;你可以使用reactive()函数来创建一个响应式对象。reactive()函数返回一个响应式引用对象&#xff0c;它包装了一个普通的对象&#xff0c;使得该对象能够成为响应式数据源。 下面是一个示例&#xff0c;演示了如何在UniApp中使用Vue3框架…