Android底层事件注入,控制系统的触摸、点击、各个按钮触发

Android底层事件注入,在知道要实现这个功能的时候,我感觉技术含量瞬间提高了很多,,涉及到底层事务。

Android实现按钮触发事件方法有多种,但并不是每种都适用,我们使用的方法是调用"sendevent"命令,这是Linux系统下的命令,在Android上使用首先要将机器获取到root权限,root过的手机才能使用Runtime.getRuntime().exec("cmd"); 方法取得操作Android底层的环境;既然要使用到这个,那么简单的介绍一下这个东西;这个东西主要就是用来模拟一套linux系统环境,在这个环境下可以通过Linux里面的一些命令实现对系统的操作,使用方法非常简单:

java代码:DataOutputStream dos = null;try {//注入su命令获取权限Process p = Runtime.getRuntime().exec("su");dos = new DataOutputStream(p.getOutputStream());System.out.println(cmd);//写入要执行的命令语句,下面语句表示列出sdcard下的文件信息,并将信息输出到dos流中,可以新建一个输入流获取dos.writeBytes("ls /mnt/sdcard\n");dos.flush();dos.writeBytes("exit\n");dos.flush();p.waitFor();} catch (Exception e) {e.printStackTrace();} finally {if (dos != null) {try {dos.close();} catch (IOException e) {e.printStackTrace();}}}

上面的代码模拟了获取sdcard下文件目录的信息岛输出流dos中的操作,我们暂把这个操作命名为“RuntimeExec操作”,需要注意的问题是:

1. exec的输入输出流需要自己处理

2. exec执行时阻塞、非阻塞,返回结果问题

3. 注意权限问题

——————————————————————————————————————————–

我们要实现向按钮、屏幕等硬件发送底层事件,需要先获取硬件设备文件权限(文件权限跟root权限不同),再调用open函数打开设备,设备文件一般在Android系统目录的dev/input结构下:

static int open_device(int index){if (index >= nDevsCount || pDevs == NULL) return -1;debug("open_device prep to open");char *device = pDevs[index].device_path;debug("open_device call %s", device);int version;int fd;char name[80];char location[80];char idstr[80];struct input_id id;fd = open(device, O_RDWR);if(fd < 0) {pDevs[index].ufds.fd = -1;pDevs[index].device_name = NULL;debug("could not open %s, %s", device, strerror(errno));return -1;}pDevs[index].ufds.fd = fd;ufds[index].fd = fd;name[sizeof(name) – 1] = ‘\0’;if(ioctl(fd, EVIOCGNAME(sizeof(name) – 1), &name) < 1) {debug("could not get device name for %s, %s", device, strerror(errno));name[0] = ‘\0’;}debug("Device %d: %s: %s", nDevsCount, device, name);pDevs[index].device_name = strdup(name);return 0;}

获取文件权限可使用“RuntimeExec操作”注入命令"chmod 777 filepath"的方法获取;一般来说dev/input目录下会有event0、event1等等文件,这些文件对应我们的一个硬件设备,比如屏幕,鼠标等

有了这些,我们就可以使用sendevent命令了。

首先android界面捕获事件的流程。用户在屏幕上点击一下后,程序里面的OnClickListener是怎样收到这个事件的。大致流程如下用户点击-(硬件驱动部分)硬件产生一个中断,往/dev/input/event*写入一个相应的信号-&gt;jni部分,android循环读取/dev/input/event*的事件,再分发给WindowManagerServer,最后再发到相应的ViewGroup和View。这里可以通过往/dev/input/event*写信号的方式,来达到模拟事件的目的,接下来关心的就是信号的协议了。

关于sendevent命令使用推荐两篇博客:

我们在做的时候基本实现了需要的功能,触摸、点击、滑屏、返回、菜单、Home、声音按钮的控制

君子当权积福,小人仗势欺人。

Android底层事件注入,控制系统的触摸、点击、各个按钮触发

相关文章:

你感兴趣的文章:

标签云: