@myron-lee
2019-04-22T08:31:41.000000Z
字数 1073
阅读 1417
一些按键的事件 Framework 层做了特殊处理,比如扫码等,应用层可以接收事件并响应,但是应用层响应逻辑无法覆盖系统响应逻辑,按下按键系统响应逻辑和应用层响应逻辑都会触发,造成冲突。
Android 系统设计上,只允许有用户界面的 Activity 接收 keyEvent,后台 Service 没有用户界面,接收不到 KeyEvent。而定制之后,我们希望有些功能可以全局触发,即我们的应用不在前台的时候,按下按键可以触发我们后台 Service 的响应逻辑,完成业务功能。
为了清除系统对一些按键的特殊处理逻辑,使应用层可以单独的做响应和处理,采用类似快捷键映射的方案,hook Android 系统物理按键事件分发处理流程,修改这些按键对应的 keyEvent,(可以修改键盘的 layout 文件,但异步 IO 可能存在延迟,建议在 FrameWork 层做 hook),并支持重置按键的 KeyEvent。采用广播的修改方式。
为了让 Service 也能收到 KeyEvent,需要在 Android 系统的物理按键事件的分发处理流程中,与我们 Service 通信,触发我们的业务功能。而与我们的业务 Service 直接通信会强依赖我们 Service 的包名和类名(通过 Implicit Intent 方式启动 Service 的方式在 Android 5.0 的时候被禁止了,存在安全问题)。所以选用广播的方式,即 Framework 层识别我们定制的按键事件,发送广播(不影响 KeyEvent 的原有分发流程,针对我们定制的按键,额外发送广播),解耦。
Android 系统物理按键事件分发处理流程:
修改按键命令广播 intent 定义
extras:bundle {'fromKeyCode': int, 'toKeyCode': int} fromKeyCode 是原 keyCode,toKeyCode 为我们自定义的新 keyCode
重置
定制按键事件广播 intent 定义
DOWN
、UP
等,string 类型。