Android 11 关于按键拦截/按键事件处理分享
1.Android 11 -- 强制清理app后台,关于权限引发的问题2.Android 11 (MTK)状态栏图标反色-->跟随当前应用变化代码流程3.Android 11 --关于Toast的异常4.Android 11 -- 关于dialog和悬浮窗导致SystemUI状态栏下拉频繁闪烁(窗口焦点问题)5.Android 11 下拉菜单长按WiFi图标SystemUI ANR6.Android 11 sim卡来电不弹出悬浮通知,默认来电默认全屏7.Android Bluetooth 蓝牙开发/蓝牙协议 小结8.Android11 —— 自定义添加一个System Services9.Android系统——AOSP相关-->随记10.Android11 , Launcher3 切换阿拉伯语,最近应用(后台)不能滑动11.Android 底层问题日志记录12.Android 11 -- app 服务保活13.Android11 - 添加自定义服务注意事项14.Android 11 导航栏添加一个虚拟按钮--问题合集15.Android 11--设置第三方Launcher并默认 与 如何预置apk16.Android11 系统修改 AOSP输入法的默认输入键盘布局17.Settings里面切换不同Launcher的代码流程18.关于Android`系统默认屏保`19.关于Android 11 Settings添加新的选项界面的细节20.Android 11 自由窗口模式 || 全屏模式启动app21.强制app横屏显示或者竖屏显示(动态)22.Android 11 禁止从SD卡上安装第三方应用23.实体物理音量键替换为home键24.AMS- kill Launcher进程的代码流程25.Android 11 recovery恢复出厂设置保留某些文件26.Android 11 禁用 adb root (userdebug版本)27.Android11 应用默认获取通知使用权限(可以获取系统所有通知信息)28.Android 11 UsbDebug 关于adb RSA 认证29.Android 11 NavigationBar && Status Bar 如果改变背景颜色30.Anroid 11 关于NotificationManager && NotificationManagerService -- 衍生到权限管理31.Android13 控制设置界面 双栏显示或单栏显示32.Android 13 大屏显示时关于SystemUI和Launcher3问题33.Android 系统适配无源码app34.Android 11 关于app的权限重置35.Android 11.0 关于app进程保活
36.Android 11 关于按键拦截/按键事件处理分享
37.Android R Settings关于屏保/PowerManagerService欺骗系统不让其进入休眠状态38.Android13 关于SystemUI更新/Nav Bar add volume button&&other button39.Android 13 移植EthernetSettings/Ethernet更新40.Anrdoir 13 关于设置静态IP后,突然断电,在上电开机卡动画41.Android T(13) The app is granted permissions by default42.Android T 关于屏幕旋转 (一)43.Android T about screen rotation(二)44.Android 13 about launcher3 (1)45.Android T don't abort background activity starts46.Android T adout replace bootanimation47.Launcher start App WINDOWING_MODE_FREEFORM48.Android 11 About SleepToken / (Settings)Screen timeout49.Settings.System数据监听/prop&SystemProperties数据监听系统在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
处理按键事件,不管是物理按键还是
SystemUI的nav_bar上的虚拟按键(使用了KeyEvent类中的,比如:KeyEvent.KEYCODE_VOLUME_UP).
主要注意的有两个函数:
interceptKeyBeforeDispatching 分发之前拦截事件
interceptKeyBeforeQueueing 加入队列之前拦截事件
长按物理音量上键弹出重启Dialog,去除Dialog界面部分选项
@Override
public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
int policyFlags) {
final boolean keyguardOn = keyguardOn();
final int keyCode = event.getKeyCode();
final int repeatCount = event.getRepeatCount();
final int metaState = event.getMetaState();
final int flags = event.getFlags();
final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;
final boolean canceled = event.isCanceled();
final int displayId = event.getDisplayId();
if (true) {
Log.d("tag", "interceptKeyTi keyCode=" + keyCode + " down=" + down + " repeatCount="
+ repeatCount + " keyguardOn=" + keyguardOn + " canceled=" + canceled);
}
//add text
Log.d("tag", "policyFlags:" + policyFlags);//长按和短按会产生不同的policyFlags
//短按流程 按下 down=true repeatCount=0 2次 抬起 down=false repeatCount=0
//长按流程 按下 down=true repeatCount++ 不断自增 抬起 down=false repeatCount=0
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {//1107296256 long //1644167168 short
if (policyFlags == 1107296256 || policyFlags == 1644167168) {
if (repeatCount == 20) {
mHandler.removeMessages(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS);
mHandler.sendEmptyMessageDelayed(MSG_DISPATCH_SHOW_GLOBAL_ACTIONS, 2000 * 1);
}
return -1;
}
}
//add text
//infrare simulate mouse
boolean isBox = "box".equals(SystemProperties.get("ro.target.product"));
if(isBox){
...
}
//
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout());
->
powerLongPress();
||
showGlobalActions();
frameworks/base/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
//dialog所有菜单选项
<string-array translatable="false" name="config_globalActionsList">
<item>emergency</item>
<item>lockdown</item>
<item>power</item>
<item>restart</item>
<item>logout</item>
<item>screenshot</item>
<item>bugreport</item>
</string-array>
@VisibleForTesting
protected void createActionItems() {
// Simple toggle style if there's no vibrator, otherwise use a tri-state
if (!mHasVibrator) {
mSilentModeAction = new SilentModeToggleAction();
} else {
mSilentModeAction = new SilentModeTriStateAction(mAudioManager, mHandler);
}
mAirplaneModeOn = new AirplaneModeAction();
onAirplaneModeChanged();
mItems.clear();
mOverflowItems.clear();
mPowerItems.clear();
String[] defaultActions = {"restart"};//getDefaultActions();//add text
ShutDownAction shutdownAction = new ShutDownAction();
RestartAction restartAction = new RestartAction();
ArraySet<String> addedKeys = new ArraySet<String>();
List<Action> tempActions = new ArrayList<>();
CurrentUserProvider currentUser = new CurrentUserProvider();
//add text
// make sure emergency affordance action is first, if needed
/*if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
addIfShouldShowAction(tempActions, new EmergencyAffordanceAction());
addedKeys.add(GLOBAL_ACTION_KEY_EMERGENCY);
}*/
//add text
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;
}
...
}
//点击dialog外,让它消失
protected static ActionsDialog mDialog;//add static
private void initializeLayout() {
setContentView(com.android.systemui.R.layout.global_actions_grid_v2);
fixNavBarClipping();
mControlsView = findViewById(com.android.systemui.R.id.global_actions_controls);
mGlobalActionsLayout = findViewById(com.android.systemui.R.id.global_actions_view);
mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public boolean dispatchPopulateAccessibilityEvent(
View host, AccessibilityEvent event) {
// Populate the title here, just as Activity does
event.getText().add(mContext.getString(R.string.global_actions));
return true;
}
});
//add text
ViewGroup black_view = findViewById(com.android.systemui.R.id.global_actions_grid_root);
black_view.setClickable(true);
black_view.setOnClickListener(v -> {
if (mDialog != null) mDialog.dismiss();
//dismissDialog();
});
//add text
mGlobalActionsLayout.setRotationListener(this::onRotate);
mGlobalActionsLayout.setAdapter(mAdapter);
//衍生案例1: 长按电源键直接关机不弹出dialog
void showGlobalActionsInternal() {
//add text
/*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);*/
mPowerManager.shutdown(false,null,false);//add text
//add text
}
//也可以修改属性实现
./frameworks/base/core/res/res/values/config.xml
<!-- Control the behavior when the user long presses the power button.
0 - Nothing
1 - Global actions menu - 长按电源按钮将显示一个包含各种全局操作选项的菜单
2 - Power off (with confirmation) 长按电源按钮将触发设备的关机动作,弹出需要用户确认的dialog
3 - Power off (without confirmation) 长按电源按钮将触发设备的关机动作,不需要用户确认
4 - Go to voice assist 长按电源按钮将启动语音助手
5 - Go to assistant (Settings.Secure.ASSISTANT) 长按电源按钮将启动设备的默认助手应用程序
-->
<integer name="config_longPressOnPowerBehavior">1</integer>
//衍生案例2: 长按power键按住三秒即可自动关机
<integer name="config_longPressOnPowerBehavior">3</integer> //先去掉dialog
@Override
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
...
case KeyEvent.KEYCODE_POWER: {
//add text 长按3s关机,达不到3s取消
if (down) {
Message msg = mHandler.obtainMessage(MSG_POWER_LONG_PRESS);
msg.setAsynchronous(true);
mHandler.sendMessageDelayed(msg,3000);
} else {
mHandler.removeMessages(MSG_POWER_LONG_PRESS);
}
//add text
break;
}
//注释掉原来的逻辑
/*case KeyEvent.KEYCODE_POWER: {
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}*/
}
Adroid11.0长按power键关机流程分析
Android 设备按键处理
一些按键模拟案例
@Override
public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
int policyFlags) {
...
} else if (keyCode == KeyEvent.KEYCODE_MENU) {
// Hijack modified menu keys for debugging features
final int chordBug = KeyEvent.META_SHIFT_ON;
//add text 模拟长按
if (event.getAction() == KeyEvent.ACTION_UP && (event.getEventTime() - event.getDownTime() > 800)) {
Log.d(TAG,"this is a KEYCODE_MENU's long press");
//to do
return -1;
}
//add text
...
}
分类:
Android
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库