安卓如何实现双击触摸唤醒点亮屏幕功能-Android framework实战开发

背景

经常有学员朋友在群里问到一个目前市场上常见的功能:
手机待机时候双击屏幕可以唤醒点亮手机屏幕功能
如何实现这个功能,经常有同学在群里求助,今天就刚好来讨论一下这个待机时候双击触摸唤醒点亮屏幕的功能的实现方案。

在这里插入图片描述

功能核心方案设计:

正常息屏待机时候,通过getevent是无法获取到任何的触摸事件,因为这个时候触摸屏驱动是没有工作,不会上报,需要息屏时候实现实现对触摸事件的输入,那么就需要考虑如何在息屏时候让触摸运行起来,这里一般可能会想到如下2个方案:

方案1、整体的息屏就是个假息屏,即息屏其实本质就是让背光关闭,但是触摸和画面等是可以正常使用,即这个息屏待机其实仅仅是背光关闭而已,但是系统app,触摸等都是正常运行的,只是没有背光看着屏幕息屏而已,这种其实整体功耗相比原来的息屏就会大很多。

方案2、息屏是正常的息屏,整体app画面也进入待机模式,不会在绘制画面等,背光也是关闭的,但是触摸驱动这个是上电的,可以识别用户的触摸事件,驱动层面识别双击后触发点亮屏幕。

下面针对2个方案进行尝试性调研

方案1可以直接framework层面修改

因为所有的power按键逻辑处理,都是需要经过PhoneWindowManager这里类进行的。所以考虑是否可以在PhoneWindowManager中对原有的power进行待机和唤醒操作进行修改。
核心思路步骤如下:

1.需要对power按键的原有息屏亮屏处理逻辑都进行屏蔽,即先让power按键按了之后没有任何反应

2.再针对power按键进行新的逻辑处理,只需要添加背光设置操作,息屏背光设置为0,亮屏恢复正常背光值

   public static  boolean isScreenLightOff = false;
    void setLightOff(){
        LightsManager lights = LocalServices.getService(LightsManager.class);
        LogicalLight mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
        isScreenLightOff =true;
        mBacklight.setBrightness(0);
    }

    void setLightOn(){
        LightsManager lights = LocalServices.getService(LightsManager.class);
        LogicalLight mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT);
        int brightness = Settings.System.getIntForUser(mContext.getContentResolver(),Settings.System.SCREEN_BRIGHTNESS,
                mPowerManager.getDefaultScreenBrightnessSetting(),UserHandle.USER_CURRENT_OR_SELF);
        isScreenLightOff =false;
        mBacklight.setBrightness(brightness);
    }

3、需要对触摸事件进行的相关的识别,让触摸事件在背光为0状态不进行派发到任何的app,只是在InputDispatcherh中进识别双击,如果一旦双击则重新调用setLightOn,让屏幕点亮

该方案总结:
1、这个修改波及很大,修改了很多的原生逻辑,很多时候也有其他逻辑修改相关的背光情况,经常可能出现修改不全等情况
2、因为本质只是关闭了背光而已,所以整体app都还在正常运行,没有进入待机状态,所以整体功耗肯定比以前大很多

方案1缺点都比较致命,所以基本上完全不推荐该方案

方案2 驱动层面实现

这个方案属于大部分厂商都使用的现成方案,具体代码和实现细节暂时不进行深入,这里可拿相关手机来进调研看看是如何做到的。

1、有一个设置开关来启动双击亮屏功能
在这里插入图片描述
打开后既可以实现在灭屏时候点击触摸屏幕2下既可以点亮

2、在灭屏时候连续点击屏幕两下,通过getevent看看是不是传递的触摸事件?

test@test:~/disk2/nx563j_aosp14$ adb shell getevent -lrt
add device 1: /dev/input/event8
  name:     "msm8998-tasha-snd-card Button Jack"
add device 2: /dev/input/event7
  name:     "msm8998-tasha-snd-card Headset Jack"
add device 3: /dev/input/event6
  name:     "uinput-fpc"
add device 4: /dev/input/event1
  name:     "proximity"
add device 5: /dev/input/event2
  name:     "light"
add device 6: /dev/input/event0
  name:     "qpnp_pon"
add device 7: /dev/input/event3
  name:     "hall_device"
add device 8: /dev/input/event4
  name:     "nubia_synaptics_dsx"
add device 9: /dev/input/event5
  name:     "gpio-keys"
[  485422.726460] /dev/input/event4: EV_KEY       KEY_WAKEUP           DOWN                
[  485422.726460] /dev/input/event4: EV_SYN       SYN_REPORT           00000000            
[  485422.726758] /dev/input/event4: EV_KEY       KEY_WAKEUP           UP                  
[  485422.726758] /dev/input/event4: EV_SYN       SYN_REPORT           00000000             rate 3355
[  485422.791717] /dev/input/event1: EV_REL       REL_RZ               0000000a            
[  485422.791717] /dev/input/event1: EV_SYN       SYN_REPORT           00000000             rate 15
[  485422.878681] /dev/input/event1: EV_REL       REL_RZ               0000000a            
[  485422.878681] /dev/input/event1: EV_SYN       SYN_REPORT           00000000             rate 11

明显可以看出getevent获取的数据这里根本没出现有任何的触摸事件的abs数据,而是变成的KEY_WAKEUP的Key事件类型,从而达到唤醒屏幕的目的,这个KEY_WAKEUP就是和正常按下POWER按钮事件一样。
正常Power的getevent展示如下:


[  485662.684341] /dev/input/event0: EV_KEY       KEY_POWER            DOWN                
[  485662.684341] /dev/input/event0: EV_SYN       SYN_REPORT           00000000            
[  485662.801875] /dev/input/event1: EV_REL       REL_RZ               0000000a            
[  485662.801875] /dev/input/event1: EV_SYN       SYN_REPORT           00000000             rate 8
[  485662.827897] /dev/input/event0: EV_KEY       KEY_POWER            UP                  
[  485662.827897] /dev/input/event0: EV_SYN       SYN_REPORT           00000000             rate 38

KEY_WAKEUP和KEY_POWER的主要区别在于它们的功能和用途不同。‌

KEY_WAKEUP通常用于在设备休眠状态下通过特定按键唤醒设备,而KEY_POWER则用于控制设备的开关机功能。

KEY_WAKEUP是一个特定的按键值,用于在设备休眠时通过中断唤醒设备。当设备处于休眠状态时,通过按下具有唤醒功能的按键(如PowerKey),会触发中断,从而唤醒设备。这与设备的电源管理密切相关,允许用户在不完全关闭设备的情况下快速恢复使用‌12。

KEY_POWER则是指用于开关机的按键,通常在设备完全关闭时使用。按下KEY_POWER键会触发设备的关机或重启过程,这与设备的启动和关闭操作直接相关‌24。

在技术实现上,KEY_WAKEUP通常与设备的输入系统(如GPIO)相关联,并在设备休眠时设置为中断源。当按键被按下时,会触发中断,从而使设备从休眠状态唤醒。而KEY_POWER键的实现则涉及到更底层的硬件控制,确保设备能够执行开关机操作‌12。
即无论WAKEUP还是POWER都可以唤醒休眠点亮屏幕。
方案总结:
驱动层面实现方案为啥成为各个厂商主流方案,主要有以下几点:

1、完全不需要修改任何的framework层面代码,不需要修改破坏任何的原生power逻辑

2、驱动部分直接就识别了双击,然后上报的一个KEY_WAKEUP事件,非常简单的实现了唤醒设备

更多framework详细代码和资料参考如下链接
投屏专题部分:

https://mp.weixin.qq.com/s/IGm6VHMiAOPejC_H3N_SNg

hal+perfetto+surfaceflinger

https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
其他课程七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

参考相关链接:
https://blog.csdn.net/zhimokf/article/details/137958615

更多framework假威风耗:androidframework007

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/888102.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【微服务】服务注册与发现 - Eureka(day3)

CAP理论 P是分区容错性。简单来说,分区容错性表示分布式服务中一个节点挂掉了,并不影响其他节点对外提供服务。也就是一台服务器出错了,仍然可以对外进行响应,不会因为某一台服务器出错而导致所有的请求都无法响应。综上所述&…

dwceqos网络驱动性能优化

文章介绍 本文会分享一些在QNX系统下对io-pkt-v6-hc驱动模块cpu loading过高问题优化的经验,以及一些调优debug的方法。这些优化措施实施之后可以降低io-pkt-v6-hc在高负载的情况下的cpu loading。本文的调优是基于synopsys公司的dwceqos模块,理论上方法…

【Android 源码分析】Activity生命周期之onPause

忽然有一天,我想要做一件事:去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

【STM32 HAL库】MPU6050 DMP库移植 与 自检失败的处理

【STM32 HAL库】MPU6050 DMP库移植 与 自检失败的处理 本文参考移植步骤文件配置代码修改inv_mpu.cinv_mpu.hinv_mpu_dmp_motion_driver.c 使用 自检失败怎么处理ret -1改正DEBUG过程 ret -9改正DEBUG过程 本文参考 B站 CSDN 移植步骤 文件配置 新建一个 dmp 文件夹 并将…

【Linux】进程地址空间、环境变量:从理论到实践(三)

🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 🚀 前言一:🔥 环境变量 🥝 基本概念🥝 常见环境变量🥝 查看环境变量方法 二:🔥 测试 &…

Nat. Commun.:飞秒激光书写受蚂蚁启发的可重构微型机器人集体

背景介绍生物在各种环境中的集体行为十分普遍,它们能够自发有序地完成单个个体难以完成的任务。目前,生物集体的形成主要分为两大类。第一类生物个体之间没有直接接触,如蜜蜂、鱼和鸟类,这导致这些集体不稳定,容易受到…

Linux网络编程 -- 网络基础

本文主要介绍网络的一些基础概念,不涉及具体的操作原理,旨在构建对网络的基础认识。 1、网络的早期发展历程 20世纪50年代 在这一时期,计算机主机非常昂贵,而通信线路和设备相对便宜。为了共享计算机主机资源和进行信息的综合处…

基于图像的3D动物重建与生成

一、背景与目标 3D-Fauna 是一款用于基于图像和视频进行四足动物3D重建与生成的开源方案。自然界展示了复杂的相似性与多样性,该方法通过学习来自网上图片的四足动物的3D形态,能够从单张图片生成可动画化的带有纹理的3D网格模型。其最终目标是通过大量扩展现有的解决方案,实…

数据库(MySQL):使用命令从零开始在Navicat创建一个数据库及其数据表(一).创建基础表

一. 使用工具和命令 1.1 使用的工具 Navicat Premium 17 :“Navicat”是一套可创建多个连接的数据库管理工具。 MySQL版本8.0.39 。 1.2 使用的命令 Navicat中使用的命令 命令命令解释SHOW DATABASES;展示所有的数据库CREATE DATABASE 数据库名称; 创…

基于STM32的数字温度传感器设计与实现

引言 STM32 是由意法半导体(STMicroelectronics)开发的基于 ARM Cortex-M 内核的微控制器系列,以其强大的处理能力、丰富的外设接口和低功耗著称,广泛应用于嵌入式系统设计中。在这篇文章中,我们将介绍如何基于 STM32…

深度学习:基于MindSpore实现ResNet50中药分拣

ResNet基本介绍 ResNet(Residual Network)是一种深度神经网络架构,由微软研究院的Kaiming He等人在2015年提出,并且在ILSVRC 2015竞赛中取得了很好的成绩。ResNet主要解决了随着网络深度增加而出现的退化问题,即当网络…

数据结构与算法——动态规划算法简析

1.初步了解动态规划 由于本篇博客属于动态规划的初阶学习,所以大多都是简单的表示,更深层次的学术用语会在之后深度学习动态规划之后出现,本文主要是带各位了解一下动态规划的大致框架 1.1状态表示 通常的我们会开辟一个dp数组来存储需要表示…

015 品牌关联分类

文章目录 后端CategoryBrandEntity.javaCategoryBrandController.javaCategoryBrandServiceImpl.javaCategoryServiceImpl.javaBrandServiceImpl.java删除 npm install pubsub-jsnpm install --save pubsub-js这个错误是由于在尝试安装 pubsub-js 时,npm 发现了项目…

数据结构(栈和队列的实现)

1. 栈(Stack) 1.1 栈的概念与结构 栈是一种特殊的线性表,其只允许固定的一段插入和删除操作;进行数据插入和删除的一段叫做栈顶,另一端叫栈底;栈中的元素符合后进先出LIFO(Last In First Out&…

C++——模拟实现vector

1.查看vector的源代码 2.模拟实现迭代器 #pragma oncenamespace jxy {//模板尽量不要分离编译template <class T>class vector{public:typedef T* iterator;//typedef会受到访问限定符的限制typedef const T* const_iterator;//const迭代器是指向的对象不能修改&#xf…

透明物体的投射和接收阴影

1、让透明度测试Shader投射阴影 &#xff08;1&#xff09;同样我们使用FallBack的形式投射阴影&#xff0c;但是需要注意的是&#xff0c;FallBack的内容为&#xff1a;Transparent / Cutout / VertexLit&#xff0c;该默认Shader中会把裁剪后的物体深度信息写入到 阴影映射纹…

毕业设计_基于springboot+ssm+bootstrap的旅游管理系统【源码+SQL+教程+可运行】【41001】.zip

毕业设计_基于springbootssmbootstrap的旅游管理系统【源码SQL教程可运行】【41001】.zip 下载地址&#xff1a; https://download.csdn.net/download/qq_24428851/89828190 管理系统 url: http://localhost:8080/managerLoginPageuser: admin password: 123 用户门户网站…

【设计模式-解释模式】

定义 解释器模式是一种行为设计模式&#xff0c;用于定义一种语言的文法&#xff0c;并提供一个解释器来处理该语言的句子。它通过为每个语法规则定义一个类&#xff0c;使得可以将复杂的表达式逐步解析和求值。这种模式适用于需要解析和执行语法规则的场景。 UML图 组成角色…

SPDK从安装到运行hello_world示例程序

SPDK从安装到运行示例程序 #mermaid-svg-dwdwvhrJiTcgTkVf {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dwdwvhrJiTcgTkVf .error-icon{fill:#552222;}#mermaid-svg-dwdwvhrJiTcgTkVf .error-text{fill:#552222;s…

android compose ScrollableTabRow indicator 指示器设置宽度

.requiredWidth(30.dp) Box(modifier Modifier.background(Color.LightGray).fillMaxWidth()) {ScrollableTabRow(selectedTabIndex selectedTabIndex, // 默认选中第一个标签containerColor ColorPageBg,edgePadding 1.dp, // 内容与边缘的距离indicator { tabPositions…