找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1606|回复: 3

转载安卓按键功能修改,技术篇。

[复制链接]
1055860440 发表于 2013-5-7 15:29:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

×
Android键盘系统——改变按键功能(1)交换两个按键的功能   

改变按键的功能最简单的方法就是交换俩个按键的功能。在做这项测试之前,先分析一下键盘布局文件和按键的原理。在明白这些之后,你就会发现只是如此的简单。

从键盘布局文件截取一部分类容:



Key 2 1
Key 158 BACK WAKE_DROPPED




其中,第二列是一个整数值,表示驱动程序中Event事件的名称。我们可以这么理解,2表示Event事件2。即当我们按下一个键时,就会有相应的中断产生,并且这个中断号是已知的。




在input.c中定义了输入设备的数据结构:其中

struct event_dev {

struct input_dev *input;

int irq;

unsigned addr;

char name[0];

};




#define KEY_BACK 158




在这个结构体中保存着中断号的信息以及另外一个非常的结构体:struct input_dev *input;。

struct input_dev *input;这个结构体的数据结构很庞大,包含的信息量很多。其中有:




struct input_id id;

unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //区分哪中输入设备

unsigned long keybit[BITS_TO_LONGS(KEY_CNT)]; //按键与按钮

unsigned int keycodemax;

unsigned int keycodesize;

void *keycode;

int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);

int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);

//以上是几个与键盘关系较密切的几个成员。,




#define KEY_BACK 158

表示的意思是事件码158(scancode)对应的字符串为KEY_BACK。Android的输入处理经过了两次映射,第一次就是将事件码映射成字符串。这个与键盘布局文件中的内容是一致的。

第二次将该字符串映射成Java的UI程序中使用的整数值(keycode)。keycode是怎么取得的呢?




在驱动层以上的KeyEvent.java中,有一个KEYCODES映射表,与KEY_BACK对应的是:

Public static final int KEYCODEA_BACK = 4;

在驱动层,有一个向用户态提供的接口:ioctl();

当ioctl()的命令参数为:EVIOCGKEYCODE时,驱动层函数的调用过程如下:

87d488f23f3791a20846e020.jpg

对于驱动层来说,哪一个键按下产生的中断是不变的(每一个按键的scancode一定),但scancode对应的字符串我们可以在键盘布局文件中修改,一旦在布局文件进行这样的修改,而KEYCODES映射表及其它内容保持不变的话,scancode对应的KEYCODE会发生变化:




修改前:

Key 2 1

Key 158 BACK WAKE_DROPPED

scancode(2)-------------ltteral(1) -------------KEYCODE(8)

scancode(158)----------ltteral(BACK) ------KEYCODE(4)

修改后:

Key 2 BACK WAKE_DROPPED

Key 158 1

scancode(2)----------------ltteral(BACK) ------KEYCODE(4)

scancode(158)-------------ltteral(1) -------------KEYCODE(8)




我们可以看到,在这种情况下,红色部分的对应关系没有变,即没有对KEYCODES映射表进行修改。而前部分对应关系改变是对键盘映射文件内容进行修改的结果。




经过这样简单的修改,就将“1”和“返回”键的功能互换了——按下“1”则能返回。但从模拟器日志打印信息可以看到,这两个键的scancode是没有发生变化的。


原帖地址http://hi.baidu.com/gengjie/item/28bd3226e61d85c9a4275a6e



















新的,好像要编译,不会啊,H大,帮忙编译个吧
   3.按键功能添加:

   对keypad来说,以SAR为例涉及到的有以下几个:
        1.首先在*.kl文件中,添加新的键值信息:Example: key   100    MEDIA_PLAY_PAUSE ,把100定义到input.h中#define KEY_PLAYPAUSE 100  

           注意:新加的键值不要与已有的重复。
        2.  ./kernel/drivers/**/input/Adc_keypad.c驱动对应的board-8726m-refc03.c中的
              adc_kp_key[]对应的键位添加自定义的键码  如 :{KEY_PLAYPAUSE ,    "playpause", CHAN_5, 419, 60},
       3.   ./frameworks/base/include/ui/keycodeLabels.h
           在数组static const KeycodeLabel KEYCODES[] 中添加 新定义的信息
                { "PLAYPAUSE", 120 },      

       4.   ./ frameworks/base/native/include/android/Keycodes.h         

            枚举类型 中添加
                    AKEYCODE_PLAYPAUSE = 120

       5.  ./frameworks/base/core/res/res/values/attrs.xml
                <enum name="KEYCODE_BUTTON_PLAYPAUSE"  value="120"/>

       6.   ./frameworks/base/core/java/android/view/KeyEvent.java
              public static final int KEYCODE_PLAYPAUSE         = 120;
              注意:要修改为    private static final int LAST_KEYCODE           = KEYCODE_PLAYPAUSE;
                           
        7.   ./frameworks/base/libs/ui/input.java

           在bool KeyEvent::isSystemKey(int32_t keyCode)()中,同样需要添加:
                 case AKEYCODE_PLAYPAUSE:

       8.   通过以上的更改,新的键值就添加上去了,注意上面标红色的数字表示必须相同的,另外由于更改了 KeyEvent,影响到了API, 所以需要make update-api
            
            如果对新键值进行处理,可以通过获取相应的keycode,对它进行处理;对于按键事件的处理一般如下文件中
frameworks/policies/base/phone/com/android/internal/policy/impl /PhoneWindowManager.java,综上可知,我们可以根据需求定义自己的键值,并对键值所对应的事件信息进行合理化处理。
       补充:  在写程序时,需要捕获KEYCODE_HOME、KEYCODE_ENDCALL、KEYCODE_POWER这几个按键,但是这几个按键系统做了特殊处 理,在进行dispatch之前做了一些操作,HOME除了Keygaurd之外,不分发给任何其他APP,ENDCALL和POWER也类似,应用程序 在View和Activity的onKeyDown/Up中是监听不到的,所以需要我们系统处理之前进行处理,我的做法是自己定义一个FLAG,在自己的 程序中添加此FLAG,然后在WindowManagerServices.java中获取当前窗口的FLAG属性,如果是我们自己设置的那个FLAG, 则不进行特殊处理,直接分发按键消息到我们的APP当中,由APP自己处理。这部分代码最好添加在

@Override

boolean preprocessEvent(InputDevice device, RawInputEvent event)方法中,这个方法是KeyInputQueue中的一个虚函数,在处理按键事件之前的一个“预处理”。

    注意:对HOME键的处理好像必需要修改PhoneWindowManager.java中的interceptKeyTi方法,具体可以参考对KeyGuard程序的处理。
87d488f23f3791a20846e020.jpg
论坛发展靠大家,积极提供资源;请勿灌水
通过分享您的互联网来赚钱
yuqing 发表于 2013-5-7 19:06:17 | 显示全部楼层
说了半天没方法,貌似别人修改都是改的framework文件夹里面的android.policy.jar或android.policy.odex,既不影响原有的功能,又添加了新功能——如音量键既可以解锁又可以调节音量......
论坛发展靠大家,积极提供资源;请勿灌水
回复

使用道具 举报

 楼主| 1055860440 发表于 2013-5-8 09:19:08 | 显示全部楼层
yuqing 发表于 2013-5-7 19:06
说了半天没方法,貌似别人修改都是改的framework文件夹里面的android.policy.jar或android.policy.odex,既 ...

大神改一个给我吧
论坛发展靠大家,积极提供资源;请勿灌水
回复

使用道具 举报

yuqing 发表于 2013-5-8 10:52:00 | 显示全部楼层
1055860440 发表于 2013-5-8 09:19
大神改一个给我吧

这个要反编译+修改+编译+签名,别看这个文件小,但是反编译后文件很大又多,看到就烦人......更何况本人就只会反编译+编译+签名就是不会修改{:soso_e101:} ......
论坛发展靠大家,积极提供资源;请勿灌水
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|存档|商匡数科 ( 沪ICP备19008575号-1 )

GMT+8, 2024-10-1 18:21 , Processed in 0.042108 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表