Android系统底层事件跨进程注入,远程控制屏幕的触摸、点击、滑动

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

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

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命令使用推荐两篇博客:

http://zuoshu.iteye.com/blog/1775606

http://blog.csdn.net/roger_ge/article/details/5552740

 

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

 

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值