Monkey源代码分析番外篇之Android注入事件的三种方法比較
原文:http://www.pocketmagic.net/2012/04/injecting-events-programatically-on-android/#.VEoIoIuUcaV
往下分析monkey事件注入源代码之前先了解下在android系统下事件注入的方式。翻译一篇国外文章例如以下。
Method 1: Using internal APIs
该方法和其它全部内部没有向外正式发布的APIs一样存在它自己的风险。
The idea is to get an instance of WindowManager in order to access the injectKeyEvent / injectPointerEvent methods.
原理是通过获得WindowManager的一个实例来訪问injectKeyEvent/injectPointerEvent这两个事件注入方法。
IBinder wmbinder = ServiceManager.getService( "window" );
IWindowManager m_WndManager = IWindowManager.Stub.asInterface( wmbinder );
The ServiceManager and WindowsManager are defined as Stubs. We can then bind to these services and call the methods we need.
ServiceManager和Windowsmanager被定义为存根Stubs类。我们依据我们的须要绑定上这些服务并訪问里面的方法。
To send a key do the following:
通过下面方式发送一个事件:
// key down
m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_A ),true );
// key up
m_WndManager.injectKeyEvent( new KeyEvent( KeyEvent.ACTION_UP, KeyEvent.KEYCODE_A ),true );
To send touch/mouse events use:
发送touch/mouse事件:
//pozx goes from 0 to SCREEN WIDTH , pozy goes from 0 to SCREEN HEIGHT
m_WndManager.injectPointerEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,pozx, pozy, 0), true);
m_WndManager.injectPointerEvent(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_UP,pozx, pozy, 0), true);
This works fine, but only inside your application
这样的方法能在你的应用中非常好的工作,但,也只只能在你的应用中而已
The moment you're trying to inject keys/touch events to any other window, you'll get a force close because of the following exception:
一旦你想要往其它窗体注入keys/touch事件,你将会得到一个强制关闭的消息:
E/AndroidRuntime(4908): java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission
Not much joy, as INJECT_EVENTS is a system permission. A possible solution is discussed here and here.
苦逼了吧,毕竟INJECT_EVENTS是须要系统权限的,一些可能解决的方案在这里和这里有讨论到。
(译者注:请查看本人上一篇翻译的《Monkey源代码分析番外篇之WindowManager注入事件怎样跳出进程间安全限制》里面有更具体针对这个问题的描写叙述)
Method 2: Using an instrumentation object
This is a clean solution based on public API, but unfortunately it still requires that INJECT_EVENTS permission.
相对以上的隐藏接口和方法,这个是比較干净(上面的是隐藏的。故须要用到android不干净不推荐的方法去获取)的方式,但不幸的事它依旧有上面的JINECT_EVENTS这个仅仅有系统应用(基本上就是android自己提供的,如monkey)才被同意的权限问题。
Instrumentation m_Instrumentation = new Instrumentation();
m_Instrumentation.sendKeyDownUpSync( KeyEvent.KEYCODE_B );
For touch events you can use:
下面是触摸事件实例:
//pozx goes from 0 to SCREEN WIDTH , pozy goes from 0 to SCREEN HEIGHT
m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_DOWN,pozx, pozy, 0);
m_Instrumentation.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(),
SystemClock.uptimeMillis(),MotionEvent.ACTION_UP,pozx, pozy, 0);
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemh1YmFpdGlhbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
All good inside the test application, and will crash instantly when trying to inject keys to outside apps, not because the approach doesn't work, but because Android Developers have chosen so. Thanks guys, you rock! Not.
在应用内操作的话全然没有问题,但一旦跳出这个应用去触发按键事件的话就会崩溃。不是由于这种方法不工作,而是由于android开发人员做了限制。谢谢你们,android的开发人员们,你牛逼!
个屁。
By looking at sendPointerSync's code, you will quickly see it uses the same approach as presented in method 1). So this is the same thing, but packed nicely in a easy to use API:
通过分析sendPointerSync的相应代码。能够看到事实上instrumentation使用到的注入事件方式事实上和方法一提到的通过WindowManager.injectPointerEvents是一样的。所以穿的都是同一条内裤,仅仅是Robotium出来走动的时候套上条时尚喇叭裤。而以上直接调用WindowManager的方式就宛如仅仅穿一条内裤出街的差别而已。
public void sendPointerSync(MotionEvent event) {
validateNotAppThread();
try {
(IWindowManager.Stub.asInterface(ServiceManager.getService("window")))
.injectPointerEvent(event, true);
} catch (RemoteException e) {
}
}
Method 3: Direct event injection to /dev/input/eventX
Linux exposes a uniform input event interface for each device as /dev/input/eventX where X is an integer. We can use it directly and skip the above Android Platform permission issues.
linux以系统设备的方式向用户暴露了一套统一的事件注入接口/dev/input/eventX(当中X代表一个整数)。
我们能够直接跳用而跳过以上的平台(android这个机遇linux的平台)限制问题。
For this to work, we will need root access, so this approach only works on a rooted device.
可是这须要工作的话,你须要rooted过的设备。
By default the eventX files have the permission set for 660 (read and write for Owner and Group only). To inject keys from our application, we need to make it writable. So do this first:
设备文件eventX默认是被设置为660这个权限的(Owner和同组成员有读写,而owner是root)。为了向这个设备注入事件。你必须让它能可写。所以请先做下面动作:
adb shell
su
chmod 666 /dev/input/event3
You will need root to run the chmod command.
你将须要root权限来执行chmod命令。
|
作者 |
自主博客 |
微信 |
CSDN |
|
天地会珠海分舵 |
服务号:TechGoGoGo 扫描码: |
http://blog.csdn.net/zhubaitian |
Monkey源代码分析番外篇之Android注入事件的三种方法比較的更多相关文章
- Android注入事件的三种方法比较
方法1:使用内部APIs 该方法和其他所有内部没有向外正式公布的APIs一样存在它自己的风险.原理是通过获得WindowManager的一个实例来访问injectKeyEvent/injectPoin ...
- Monkey源代码分析番外篇WindowManager如何出的喷射事件的进程间的安全限制
在分析monkey源代码时的一些背景知识不明确,例如看到monkey它是用windowmanager的injectKeyEvent的喷射事件时的方法.我发现自己陷入疙瘩,这种方法不仅能够在当前的应用程 ...
- monkey源代码分析之事件注入方法变化
在上一篇文章<Monkey源代码分析之事件注入>中.我们看到了monkey在注入事件的时候用到了<Monkey源代码分析番外篇之Android注入事件的三种方法比較>中的第一种 ...
- Monkey源代码分析之事件注入
本系列的上一篇文章<Monkey源代码分析之事件源>中我们描写叙述了monkey是怎么从事件源取得命令.然后将命令转换成事件放到事件队列里面的.可是到如今位置我们还没有了解monkey里面 ...
- Second Day: 关于Button监听事件的三种方法(匿名类、外部类、继承接口)
第一种:通过匿名类实现对Button事件的监听 首先在XML文件中拖入一个Button按钮,并设好ID,其次在主文件.java中进行控件初始化(Private声明),随后通过SetOnClickLis ...
- python学习番外篇——字符串的数据类型转换及内置方法
目录 字符串的数据类型转换及内置方法 类型转换 内置方法 优先掌握的方法 需要掌握的方法 strip, lstrip, rstrip lower, upper, islower, isupper 插入 ...
- 快速定位 Android APP 当前页面的三种方法(Activity / Fragment)
方法一.通过adb命令打印当前页面: Android 如何快速定位当前页面是哪个Activity or Fragment (1)查看当前Activity :adb shell "dumpsy ...
- android 获取sharedpreference的三种方法的区别
1. public SharedPreferences getPreferences (int mode) 通过Activity对象获取,获取的是本Activity私有的Preference,保存在系 ...
- android 设置颜色的三种方法
1.利于系统自带的颜色类 如TextView1.setTextColor(Android.graphics.Color.RED); 2.数字颜色表示法 TextView1.setTextColor(0 ...
随机推荐
- (C++)UrlEncode的标准实现
http://blog.163.com/xiaopengyan_109/blog/static/149832173201072685539394/ 地址栏传中文参数后是什么编码格式 网页中的表单使用P ...
- android 随手记 读写文件的几种方式
java中多种方式读文件 一.多种方式读文件内容. 1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取文件内容 4.随机读取文件内容 */ import java.io.BufferedRe ...
- 关于csdn博客中案例效果的动态演示
在曾经一篇博文中,网友评论说要是案例效果是动态演示的就好了,我认为说的非常是有道理.由于一个简单的截图不能非常好的展示案例效果.要是有一张gif图能动态的播放案例效果就再好只是了.在这里提供一个小软件 ...
- SSO是什么?
SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信仸的应用系统.它包括可以将这次主要的登录映射到其他应用中用亍同一个用户的登录的机制 ...
- taro alias 的使用
用来配置目录别名,从而方便书写代码引用路径.例如,使用相对路径书写文件引用如下: import A from '../../componnets/A' import Utils from '../.. ...
- 设置python 命令行交互程序自己主动补齐
1. 新建Python环境变量配置文件: vim ~/.pystartup # Add auto-completion and a stored history file of commands to ...
- Stage3d AGAL GPU处理照片 旧照片效果 sepia || pixelbender
如果看不到下边的flash,请更新flash player到最新版本. 利用AGAL实现旧照片效果,大家可以对照一下之前一篇文章,关于图像处理(pixelbender).硬件处理肯定会更快,但这里无法 ...
- opencv实现gamma灰阶检測
简单介绍 本篇解说使用opencv来測试,表示camera gamma參数的灰阶卡图片指标:YA Block.DynamicRange.Gray Scale. 详细实现 实现代码 #include & ...
- Start-Sleep 帮助信息
如下说明是翻译: help Start-Sleep 产生的帮助信息.译者: Edengundam(马涛) Start-Sleep 大纲使shell, 脚本, 或运行空间的活动挂起指定的时间. 语法St ...
- 微信小程序独家秘笈之左滑删除
代码地址如下:http://www.demodashi.com/demo/14056.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...