Android中三种注入事件方法比较

作者:junjie 时间:2022-11-20 18:17:23 

方法1:使用内部APIs

该方法和其他所有内部没有向外正式公布的APIs一样存在它自己的风险。原理是通过获得WindowManager的一个实例来访问injectKeyEvent/injectPointerEvent这两个事件注入方法。


IBinder wmbinder = ServiceManager.getService( "window" );
IWindowManager m_WndManager = IWindowManager.Stub.asInterface( wmbinder );


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 );


发送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);


这种方法能在你的应用中很好的工作,但,也仅仅只能在你的应用中而已

Android中三种注入事件方法比较

一旦你想要往其他窗口注入keys/touch事件,你将会得到一个强制关闭的消息:

Android中三种注入事件方法比较

方法2: 使用instrumentation对象

相对以上的隐藏接口和方法,这个是比较干净(上面的是隐藏的,故需要用到android不干净不推荐的方法去获取)的方式,但不幸的事它依然有上面的JINECT_EVENTS这个只有系统应用(基本上就是android自己提供的,如monkey)才被允许的权限问题。


Instrumentation m_Instrumentation = new Instrumentation();
m_Instrumentation.sendKeyDownUpSync( KeyEvent.KEYCODE_B );


以下是触摸事件实例:


//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);

Android中三种注入事件方法比较

在应用内操作的话完全没有问题,但一旦跳出这个应用去触发按键事件的话就会崩溃。不是因为这个方法不工作,而是因为android开发人员做了限制。谢谢你们,android的开发者们,你牛逼!个屁。

通过分析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) {
}
}

方法3:直接注入事件到设备/dev/input/eventX

linux以系统设备的方式向用户暴露了一套统一的事件注入接口/dev/input/eventX(其中X代表一个整数)。我们可以直接跳用而跳过以上的平台(android这个机遇linux的平台)限制问题。但是这需要工作的话,你需要rooted过的设备。

设备文件eventX默认是被设置为660这个权限的(Owner和同组成员有读写,而owner是root)。为了向这个设备注入事件,你必须让它能可写。所以请先做以下动作:

Android中三种注入事件方法比较


adb shell
su
chmod 666 /dev/input/event3


你将需要root权限来运行chmod命令。

标签:Android,注入,事件,方法
0
投稿

猜你喜欢

  • 解决idea web 配置相对路径问题

    2022-01-12 06:48:40
  • C#数据结构之单链表(LinkList)实例详解

    2021-09-15 21:40:14
  • Windows下搭建Flutter开发环境

    2023-11-06 01:32:52
  • Android Studio如何打包生成APK

    2022-10-18 04:19:23
  • FeignClient如何通过配置变量调用配置文件url

    2023-05-07 08:19:25
  • JavaWeb详细讲述Cookie和Session的概念

    2022-03-23 08:39:44
  • C#中Dictionary<TKey,TValue>排序方式的实现

    2021-07-13 10:59:10
  • java 读取本地文件实例详解

    2023-08-12 20:41:32
  • 如何优雅的处理Spring Boot异常信息详解

    2023-11-29 09:50:02
  • @NonNull导致无法序列化的问题及解决

    2021-07-21 23:07:33
  • android JSON解析数据 android解析天气预报

    2022-01-16 03:33:53
  • 在 Java 中将Object 转换为 Int的四种方法

    2023-05-05 21:37:30
  • 聊聊Spring——AOP详解(AOP概览)

    2023-11-01 04:44:18
  • Android通知栏微技巧一些需要注意的小细节

    2021-10-07 12:40:59
  • C#队列Queue用法实例分析

    2023-02-27 22:35:14
  • C# Timer控件学习之使用Timer解决按钮幂等性问题

    2021-07-07 11:26:09
  • java实现拼图游戏

    2022-09-21 11:14:19
  • javaweb实现app扫码登录功能

    2022-03-25 03:48:19
  • Java 重入锁和读写锁的具体使用

    2023-09-10 11:06:54
  • Android popupWindow弹出窗体实现方法分析

    2021-08-08 08:07:42
  • asp之家 软件编程 m.aspxhome.com