设为首页收藏本站

数字电视开发论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

新浪微博登陆

只需一步, 快速开始

快捷登录

胜天工科技销售各种数字电视信号调制卡胜天工科技销售各种数字电视信号码流卡

【游客、新手、注册会员的区别】 【积分策略和会员晋级说明】 【发帖和附件上传规则】 【如何下载感兴趣的资料】 【如何获取梦游币】 【侵权资料处理及免责说明】
查看: 1208|回复: 0

Android系统模拟鼠标键盘详解

[复制链接]
  • TA的每日心情
    开心
    昨天 19:28
  • 签到天数: 2138 天

    [LV.Master]伴坛终老

    新浪微博达人勋

    发表于 2014-12-7 22:32:33 | 显示全部楼层 |阅读模式
    分享到:
    消息来自- 北京
    在Android系统下模拟鼠标键盘等输入设备,网络上资料非常多。但不少是人云亦云,甚至测试都不愿测试一下就抄上来了。这次写一点体会,当作抛砖引玉。

    0. 背景知识:

    众所周知,Android是将Framework架在Linux之上的系统。Linux层和硬件打交道,Framework通过JNI等途径得到底层信息。
    消息的传递是:Linux -> Framework -> Application
    因为此架构的特性,我们很容易知道可以在哪些环节,以何种途径加入鼠标和键盘消息。

    1. 添加鼠标键盘消息的方法:
    我们知道消息传递的路径,就很清楚可以在哪些环节把我们需要的键盘鼠标消息添加进去了。

    1.1: Linux Driver 层面添加:
    可以写一个Linux Driver,注册一个字符设备驱动程序,建立一个虚拟的字符设备,主设备号13。利用Ioctl()和应用程序沟通。
    之前在Linux 2.4时代,Sam曾在S3C2440A上写过这样一个Driver,个人起名叫VInput。可以实现以上功能。
    优点:很少。
    缺点:
    1.编程较为复杂。Linux Kernel从2.4到2.6,再到3.0。Kernel变动不小,仅字符设备驱动程序的注册方法和Device的建立方法都有不小的变化,devfs也不支持了。
    2. 需要有对应目标平台的Kernel Source Code。
    3.需要有root权限,才能够insmod ko文件。

    总结:这个方法并不好用。除了专业写Driver的朋友外,估计没有人会这么干。有一次曾想把Linux Kernel 2.4时代的VInput移植到Linux Kernel3.0来。但内核符号改变太大。没能实现。

    1.2:  Linux 用户层面添加:
    在Linux Kernel 2.6的某个版本中,添加了UInput。即Input User level driver.  这个Driver允许应用程序通过和 /dev/uinput交互来创建一个新的Linux Input Device。 这个Device可以是Keyboard, Mouse,绝对位置设备等等。既然Linux 层面都模拟出具体设备了。则Framework更会认为这是个实实在在的输入设备。则我们模拟出的消息会一路上传,一直传递到App层面。
    具体方法:
    http://blog.sina.com.cn/s/blog_602f87700100llew.html

    优点:
    程序简单易行,不需要Kernel Source Code。可以模拟几乎一切常见的输入设备。
    缺点:
    这个程序最好是使用NativeC程序写成一个可执行程序。只在Linux层运行。
    但如果才用JNI把它做成一个库,供上层Android程序调用。则有可能会遇到一个问题:权限不足。
    我们在Android系统下常看到/dev/input设备的拥有者是system.  同组的其它用户的权限常常是不可读写。而一般的APK的拥有者并不是system, 所以无法读写这个设备(/dev/uinput). 所以此方法在JNI方式下有可能会失败。
    除非/dev/uinput的权限是666. 则没有问题。
    (当然也有两个办法突破,但那是另一个话题了, 可以看看以下文档系统签名部分:
    http://blog.sina.com.cn/s/blog_602f87700101jm9b.html)

    总结:这个方法Sam一直在实际使用。效果很不错。

    1.3: Framework 层面修改:
    这个办法只是理论上可行,可以在Framework 读取/dev/eventX 的JNI部分去下手。但实际上没有人会为了这个功能去破坏Framework的稳定。所以只是理论上可行。以前一个同事曾研究过这一块。但没有最终动手做。

    总结:除非有特殊需求,否则不要这么做。

    1.4: 利用Instrumentation发送键盘鼠标消息:
    Instrumentation可以监听系统和应用程序之间的通讯。可以利用它给应用程序发送鼠标键盘消息。有点像Windows下的Hook。

    具体方法:
    如果仅想向本应用程序发送键盘鼠标消息。
    Instrumentation inst=new Instrumentation();
    inst.sendKeyDownUpSync(KeyEvent.KEYCODE_A);
    inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 100, 200, 0));
    SystemClock.sleep(1000);
    inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 200, 200, 0));
    SystemClock.sleep(1000);
    inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 200, 200, 0));


    发送键盘和鼠标消息给当前有焦点的窗口。
    可以采用:
    sendKeyDownUpSync()
    sendKeySync()
    sendCharacterSync()等方式发送键盘消息。

    可以使用sendPointerSync()发送鼠标消息。


    但如果想向其它App的窗口发送键盘鼠标消息。仅仅这样做就会出错,程序会Crash。
    java.lang.SecurityException: Injecting to another application requires INJECT_EVENT permission.

    好的,我们加上这个权限。
    在AndroidManifest.xml 的Permissions选单中,添加Uses Permission.选中INJECT_EVENT.

    此时 uses-permission android:name="android.permission.INJECT_EVENT" 被加入。
    但编译时会报错,这个权限仅有System APP才能拥有。
    呵呵,那只好再加系统权限了。

    android:sharedUserId="android.uid.system">
    加入。
    生成未签名的APK。 再使用apktools加上系统签名文件。这样,就可以向其它APP发送鼠标键盘消息了。


    优点:简单易行。
    缺点:如果向其它程序发送鼠标键盘,则需要系统签名文件。且一些程序估计从更底层拿消息,所以会产生在这类程序中无响应的情况。

    总结:想向其它APP Window 发送消息。则一定需要系统签名。


    总的看来,在Android系统中模拟鼠标键盘。采用UInput方案且在Linux层做NativeC可执行程序最为稳妥。在Linux层面就直接创建了输入设备。
    如果采用Instrumentation方式,一方面一些APP可能不吃,另一方面,如果想向其它APP发送消息。则需要系统签名文件。
    踩过的脚印
    您需要登录后才可以回帖 登录 | 注册 新浪微博登陆

    本版积分规则

    嗨!您好:
    欢迎来到数字电视开发论坛。
    我的名字叫梦梦
    很高兴能够为您服务!
    如果已经注册【立即登录】
    还没有账号请【注册】
    嗨!您好:
    欢迎来到数字电视开发论坛。
    我的名字叫梦梦
    很高兴能够为您服务!
    如果已经注册【立即登录】
    还没有账号请

    QQ|小黑屋|手机版|Archiver|数字电视开发网 ( 京ICP备16008897号-5   

    GMT+8, 2018-7-20 03:28 , Processed in 0.168415 second(s), 40 queries , Gzip On.

    Powered by Discuz! X3.1

    © 2001-2013 Comsenz Inc.

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