理论:
一个Android产品所有的按键分为三大类:
- global key
通用按键,例如AKEYCODE_TV,这些key我们可以修改frameworks\base\core\res\res\xml\Global_keys.xml自己指定。 - system key
系统按键,例如AKEYCODE_HOME(home键) AKEYCODE_VOLUME_DOWN(音量键)。 - user key
用户按键,例如AKEYCODE_A AKEYCODE_B AKEYCODE_1等。
其中system key和user key都是有特殊用途的,所以我们要想实现一键启动的需要必须使用global key,物理硬件上需要有一个额外的没有其他功能的按键来作为启动键。
思路:
硬件: 一个没有其他功能的按键来作为启动键(global key)。
Linux: 写一个按键驱动,捕获按键事件,并上报,假设上报KEY_TV。
Android:获取Linux驱动上报的按键事件,截获AKEYCODE_TV(Linux上报KEY_TV,Android中对应AKEYCODE_TV)按键事件,然后处理(启动一个app,或者打开设置界面等)。
说明:
之前使用过广播的形式,在framework中捕获到对应的按键事件就发送一个广播,然后写一个app,静态注册一个广播接收器,当接收到framework发送的广播说明有用户按下按键,这时在广播接收器中启动对应的app。但是Android5.0之后,Google对发送广播做出了一些处理,当注册广播接收器的app被后台杀死后就无法再接收广播,也就无法再通过这个广播接收器启动其他app了。为了解决这个问题,我摒弃了发送广播的方法,采用修改Android系统源码,在framework层截取输入事件,直接启动其他APP。
关于按键事件:
Linux驱动上报的按键事件称之为EV_KEY,或者scancode 例如KEY_1 KEY_A等。
/system/usr/keylayout/Generic.kl(keylayout文件,Linux层的scancode到Android层的AKEYCODE的对应关系)。
表示按键 对应Linux层(scancode KEY_2) 对应Android层(AKEYCODE_1 AKEYCODE_TV)
key 2 1
key 377 TV
如果你想自定义global key,则需要按照上面的格式修改Generic.kl添加一项即可。
Android的framework接收的按键事件称之为AKEYCODE(Android KEY CODE), 例如AKEYCODE_1 AKEYCODE_A
/system/usr/keychars/Generic.kcm(key character map文件,用来表示Android按键即AKEYCODE_A对应哪个字符,或者同时按下其他按键(shift/capslock)后,对