这几天在研究android在app层次的模拟按键的实现。稍微做下记录。目前为止,网上大侠们有以下几种方案
1. 利用IWindowManager的injectKeyEvent。但是这个api在1.6之前是可以用的,但是到了1.6之后,Google以安全为由hide掉了。但是网上大虾们一直说是可以用java的反射机制来调用这个api。我试过了,发送KEYCODE_HOME的ACTION_DOWN和ACTION_UP,返回值都是成功的。但是不知为何就是没有最终调用到home。有机会再试,具体代码太乱了,大家如果有兴趣可以参考TUIOService这份代码。里面有放射机制的具体使用方法。而且据这个作者声称在froyo里面steal IWindowManager是成功的。
2. 另一个方法是往Android的StatusBar里添加home、back等按钮并实现,因为这个方案跟我的需求不符合,所以我未做测试和研究。有兴趣可以参考http://blog.csdn.net/shiningmm/article/details/5461506
3. 还有一个方法是模仿framework里statusbar的实现方式,做了一套,这哥们将源代码和资源文件都给出来了。可以参考http://blog.csdn.net/voidinit/article/details/5791278。这个牵涉到framework的更改。我未做深入研究。
4. 另一个不知道能不能用,权当留个参考,Android的Instrumentation这个类里面有个sendKeyDownUpSync方法,这个方法sdk里是公开的,且这个方法最终也是调用到IWindowManager下,但是我自己写的测试代码是没通过,可能是调用方法不当。
试了近一天的时间,上面的方法都没成功。我自己的特定情况下,我当前的设备是拥有root权限的,因此决定用下面这个方法。
5. 执行shell命令:input。
input应该是模拟从驱动往framework发的过程,直接往framework发送按键消息,以达到模拟的过程。测试过程如下:
1. 首先,将模拟器赋予root权限:
adb shell
mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
cd /system/bin
cat sh > su
chmod 4755 su
su
这种root方法,貌似每次重启模拟器都需要重新root。
2. 执行input keyevent <keycode>就可以起到作用了。
对于如何在android的应用程序中调用shell命令,网上内容很多。这里不做深究。
但是使用过程中,如果直接调用input keyevent KEYCODE_HOME,会提示killed之类的内容,换成数字就好了。具体数字和按键映射如下图:
比如 input keyevent 3 就模拟了一个home按键