Android 11 关于按键拦截/按键事件处理分享
系统在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java处理按键事件,不管是物理按键还是
SystemUI的nav_bar上的虚拟按键(使用了KeyEvent类中的,比如:KeyEvent.KEYCODE_VOLUME_UP).
主要注意的有两个函数:
interceptKeyBeforeDispatching 分发之前拦截事件
interceptKeyBeforeQueueing 加入队列之前拦截事件
长按物理音量上键弹出重启Dialog,去除Dialog界面部分选项
@Overridepublic 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 textLog.d("tag", "policyFlags:" + policyFlags);//长按和短按会产生不同的policyFlags//短按流程 按下 down=true repeatCount=0 2次 抬起 down=false repeatCount=0//长按流程 按下 down=true repeatCount++ 不断自增 抬起 down=false repeatCount=0if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {//1107296256 long //1644167168 shortif (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 mouseboolean 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>@VisibleForTestingprotected void createActionItems() {// Simple toggle style if there's no vibrator, otherwise use a tri-stateif (!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 textShutDownAction 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 textfor (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() {@Overridepublic boolean dispatchPopulateAccessibilityEvent(View host, AccessibilityEvent event) {// Populate the title here, just as Activity doesevent.getText().add(mContext.getString(R.string.global_actions));return true;}});//add textViewGroup 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 textmGlobalActionsLayout.setRotationListener(this::onRotate);mGlobalActionsLayout.setAdapter(mAdapter);//衍生案例1: 长按电源键直接关机不弹出dialogvoid 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 - Nothing1 - Global actions menu - 长按电源按钮将显示一个包含各种全局操作选项的菜单2 - Power off (with confirmation) 长按电源按钮将触发设备的关机动作,弹出需要用户确认的dialog3 - 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 @Overridepublic 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 textbreak;}//注释掉原来的逻辑/*case KeyEvent.KEYCODE_POWER: {EventLogTags.writeInterceptPower(KeyEvent.actionToString(event.getAction()),mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);// Any activity on the power button stops the accessibility shortcutcancelPendingAccessibilityShortcutAction();result &= ~ACTION_PASS_TO_USER;isWakeKey = false; // wake-up will be handled separatelyif (down) {interceptPowerKeyDown(event, interactive);} else {interceptPowerKeyUp(event, interactive, canceled);}break;}*/
}
Adroid11.0长按power键关机流程分析
Android 设备按键处理
一些按键模拟案例
@Overridepublic long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,int policyFlags) {...} else if (keyCode == KeyEvent.KEYCODE_MENU) {// Hijack modified menu keys for debugging featuresfinal 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 doreturn -1;}//add text...}
相关文章:
Android 11 关于按键拦截/按键事件处理分享
系统在frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java处理按键事件,不管是物理按键还是 SystemUI的nav_bar上的虚拟按键(使用了KeyEvent类中的,比如:KeyEvent.KEYCODE_VOLUME_UP). 主要注意的有两个函数: interceptKeyBef…...
最新TomatoIDC开源虚拟主机销售系统源码/有插件系统模块+模版系统
源码简介: 最新TomatoIDC开源虚拟主机销售系统源码,它有一个方便扩展的插件和模版系统模块,使用实用。 TomatoIDC,一款遵循GPL3.0协议的开源虚拟主机销售系统,不仅有着可以轻松扩展的插件系统和模版系统,…...
简单的docker学习 第4章docker容器
第4章 Docker容器 4.1 容器基础 4.1.1 容器启动流程 通过 docker run 命令可以启动运行一个容器。该命令在执行时首先会在本地查找指定的镜像,如果找到了,则直接启动,否则会到镜像中心查找。如果镜像中心存在该镜像,则会下载到…...
PHP中如何声明数组
数组是一种数据结构,用于存储一系列的值或对象,这些值或对象可以通过索引(或键)来访问。在PHP中,数组是一种复合类型的数据结构,可以存储多个值,这些值可以是整型、字符串、布尔值,甚…...
JavaScript前端面试题——fetch
什么是fetch? fetch:fetch是浏览器内置的api,用于发送网络请求 ajax&axios&fetch的关系 ajax:ajax 是一种基于原生 JavaScript 的异步请求技术。它使用 XMLHttpRequest 对象来发送请求和接收响应。 axios:…...
在Qt中获取Windows中进程的PID
主要是用到了系统自带的工具【tasklist.exe】 利用 QProcess调用这个tasklist有一点坑,已经在代码中指出了。 指定为csv格式输出的话,在后处理时比较方便。 QList<quint64> listProcessIdentifier(QString processName) {QProcess process;QStrin…...
8.1-java+tomcat环境的配置+代理
一、回顾 1.安装nodejs,这是一个jdk一样的软件运行环境 yum -y list installed|grep epel yum -y install nodejs node -v 2.下载对应的nodejs软件npm yum -y install npm npm -v npm set config .....淘宝镜像 3.安装vue/cli command line interface 命令行…...
gorm框架实现基本的增删改查
连接数据库 package mainimport ("github.com/jinzhu/gorm"_ "github.com/jinzhu/gorm/dialects/mysql" )func main() {db, err : gorm.Open("mysql","root:roottcp(127.0.0.1:3306)/test?charsetutf8mb4&parseTimeTrue&locLocal…...
AUTOSAR介绍
1、AUTOSAR架构介绍 AUTOSAR(AUTomotive Open System ARchitecture,汽车开放系统架构)是汽车和软件行业领先公司的全球合作联盟,为智能移动开发和建立标准化的软件框架以及开放的E/E系统架构。考虑到目前和未来市场中不同的汽车E/E架构,AUTOS…...
10. 计算机网络HTTP协议
1. 前言 无论是作为后端开发、前端开发、测试开发程序员或者是运维人员,在面试过程中,大概率都会被问到 HTTP 协议相关题目。 因为伴随着 2010 年之后移动互联网在全世界的高速发展,各种各样的浏览器(Chrome、FireFox、Safari 等)层出不穷,也诞生了诸多服务端开发的语言…...
“职场中,不要和上司作对”,真的很重要吗?你认同这句话吗?
在职场上,领导对下属的期望永远都只有两个字,不是忠诚,也不是能力,而是省心。 领导对下属的要求就是别让我操心。 在职场中,通常面临的首要问题就是如何与领导相处。 把职场中的前辈当作老师来尊重,你尊…...
可视化目标检测算法推理部署(一)Gradio的UI设计
引言 在先前RT-DETR模型的学习过程中,博主自己使用Flask框架搭建了一个用于模型推理的小案例: FlaskRT-DETR模型推理 在这个过程中,博主需要学习Flask、HTML等相关内容,并且博主做出的页面还很丑,那么,是…...
【PyTorch】基于YOLO的多目标检测项目(一)
【PyTorch】基于YOLO的多目标检测项目(一) 【PyTorch】基于YOLO的多目标检测项目(二) 目标检测是对图像中的现有目标进行定位和分类的过程。识别的对象在图像中显示有边界框。一般的目标检测方法有两种:基于区域提议的…...
spring boot 实现 Stream 钉钉事件订阅
1: 参考链接 https://open.dingtalk.com/document/orgapp/develop-stream-mode-push-server 2:钉钉开放平台订阅配置 配置之后运行一下上面提供的链接 里面的main方法,验证通道 3:订阅启动方式 EventListenerThread eventListenerThrea…...
基于 Rough.js 的 Vue 散点图绘制
本文由ScriptEcho平台提供技术支持 项目地址:传送门 基于 Rough.js 的 Vue 散点图绘制 应用场景 本代码展示了如何使用 Rough.js 库在 Vue 应用程序中绘制散点图。Rough.js 是一个轻量级 JavaScript 库,用于创建具有手绘风格的可视化效果。散点图是一…...
【c++】用c++指针传递来模拟“靶向治疗”
一:源码: #include <iostream>void targetedTherapy(bool* flag) {if (*flag == false) {*flag = true;} }int main() {//代表一系列癌细胞//true为健康细胞 false为癌变细胞bool cancerCell[7] = {true, false, true, true, true, true, false};for (int i = 0; i &…...
如何开启idea中的断言功能?
目录 一、什么是断言? 二、Java断言的语法 三、开启断言 一、什么是断言? 断言(assert)是 Java 中的一条语句,一种在程序中的逻辑(如一个结果为真或假的逻辑判断式),目的是验证软…...
大模型之语言大模型技术
本文作为大模型综述第二篇,介绍语言大模型基本技术。 近年来,在 Transformer 架构基础上构建的预训练语言模型为自然语言处理领域带来了一系列突破式进展,成为人工智能主流技术范式。预训练语言模型采用“预训练+微调”方法,主要分为两步: 1)将模型在大规模无标注数据上…...
浮点数例外 (核心已转储) 的问题记录
一般这种问题,是程序运行过程中出现浮点数运算错误导致的程序崩溃 浮点异常可能由以下几个原因引起: 除以零:当程序中出现除以零的操作时,会触发浮点异常。例如,当一个数除以0时,会导致浮点异常。数值溢出…...
Vite项目中根据不同打包命令配置不同的后端接口地址,proxy解决跨域
在vite.config.ts同级目录添加两个文件 .env.development #开发环境 VITE_APP_ENV developmentVITE_APP_BASE_API .env.production #生产配置 VITE_APP_ENV productionVITE_APP_BASE_API https://www.bdjw.work代码中使用路径 const request axios.create({baseURL: i…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
C#学习第29天:表达式树(Expression Trees)
目录 什么是表达式树? 核心概念 1.表达式树的构建 2. 表达式树与Lambda表达式 3.解析和访问表达式树 4.动态条件查询 表达式树的优势 1.动态构建查询 2.LINQ 提供程序支持: 3.性能优化 4.元数据处理 5.代码转换和重写 适用场景 代码复杂性…...
提升移动端网页调试效率:WebDebugX 与常见工具组合实践
在日常移动端开发中,网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时,开发者迫切需要一套高效、可靠且跨平台的调试方案。过去,我们或多或少使用过 Chrome DevTools、Remote Debug…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...
门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
