Android 跨进程模拟点击,Android 跨进程事件处理(一)——模拟点击、全局截屏...

一直都是在这上面找资料,无耻的我真的不好意思不再分享了。

之前分配到的任务找资料一直也是找不到,运气好的遇到个提边角料的。但是都没有实质可以用的。发文档的也都是东贴贴别人的,西找找别人的。基本都是漫天胡扯。

好了,废话不多说。直接进入今天的主题吧。

模拟点击

模拟点击和截屏其实在应用本身中实现其实很简单。但是跨进程就相对比较麻烦了。比如,你写一个程序,自动启动微信,点微信界面里的某几个按钮。

如果你也是在找技术文档,那么你看到的什么input方法啦,模拟eventMotion方法之类的就不要去测试了,都不能跨进程。

正解是:getevent/sendevent(都需要应用于root的手机)

其实说白了,android里的各种事件,都是由/dev/input/event*管着的。管屏幕点击的event,一般是eventname中含有touch或者screen之类的event

例如我的手机(手机连在电脑上,进入命令行,获得adb的操作。命令是adb shell。如果发现不起作用,就把adb的环境变量配置一下,就是你的ndk根目录,配到path中就可以了。)68e93709419891570c48d06734d0a97b.pngae80e764385921114058c743136f2c4e.png,例如我的手机,“#”代表我的手机是完全root的手机。

之后getevent -p你就会发现列出了很多设备。其中name中含有touch或者screen的应该就是管理手机触摸事件的event,不同的手机管理触摸事件的event可能不太相同。例如我的手机是event3。b5b0833ee8257b2f068c9e60060a921f.png。其中给你还可以看到一些它给出的操作用例。

下面就来说这个怎么用吧。首先,你要给你所需要的那个event授予权限。授权的时候再cmd里你只需要用chmod 777 /dev/input/event3就可以了。但是在android程序代码里就不能这样了,你修改权限的时候是需要先获得root权限的。

具体用法:

调用下面的方法就可以了。RootCmd("chmod 777 /dev/input/event3");

public static boolean RootCmd(String cmd){

Process process = null;

DataOutputStream os = null;

try{

process = Runtime.getRuntime().exec("su") ;

os = new DataOutputStream(process.getOutputStream());

os.writeBytes(cmd+ "\n");

os.writeBytes("exit\n");

os.flush();

process.waitFor();

} catch (Exception e) {

return false;

} finally {

try {

if (os != null) {

os.close();

}

process.destroy();

} catch (Exception e) {

}

}

return true;

}

授权完毕后就可以模拟点击了。

该方法是我通过分析getevent的事件得到的(之后会给出getevent的模拟过程)

private static String deviceTouchEvent = "event1";

private static final String TAG="Ctrl_System_Action";

// private static boolean isTouch

public static void setMouseClick(int x, int y) {

try {

Log.i("", "ActivityManager test User click");

/**

* sendevent /dev/input/event3 3 57 0

* sendevent /dev/input/event3 3 48 1

* sendevent /dev/input/event3 3 53 379

* sendevent/dev/input/event3 3 54 483

* sendevent /dev/input/event3 0 2 0

* sendevent /dev/input/event3 0 0 0

* sendevent /dev/input/event3 3 48 0

* sendevent /dev/input/event3 0 2 0

* sendevent /dev/input/event3 0 0 0

*/

Log.i("", "ActivityManager test User temp click x="+x+",y="+y);

// 获取可touch设备名称

String eventFirst = "/dev/input/";

String temp = "";

// 默认触摸event为event1

String myUserEventName = "event1";

String tempEventName = "";

// 获取root权限

if (!isRoot) {

RootCmd("chmod 777 /dev/input/event3");

isRoot = true;

}

if(!isGetEventName){

// 获取所有设备信息

InputStream is = Runtime.getRuntime().exec("getevent -p")

.getInputStream();

InputStreamReader isReader = new InputStreamReader(is);

BufferedReader bufferReader = new BufferedReader(isReader);

// 鉴别设备

while ((temp = bufferReader.readLine()) != null) {

Log.i("", "ActivityManager test User getEventString temp = "

+ temp);

// 先将 event*存下来

if (temp.indexOf(eventFirst) >= 0) {

if ((temp.indexOf(eventFirst) + eventFirst.length()) < temp

.length()) {

tempEventName = temp.substring(temp.indexOf(eventFirst)

+ eventFirst.length());

}

Log.i("","ActivityManager test User getEventString EventName = "

+ tempEventName);

}

// 判断设备是否为屏幕设备,如果是就将event保存下来

if (temp.indexOf("name:") >= 0

&& (temp.indexOf("touch") >= 0 || temp

.indexOf("screen") >= 0)) {

myUserEventName = tempEventName;

deviceTouchEvent = myUserEventName;

Log.i("",

"ActivityManager test User getEventString TrueEventName = "

+ tempEventName);

break;

}

}

isGetEventName = true;

}

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 3 57 0");

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 3 48 1");

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 3 53 "+x);

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 3 54 "+y);

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 0 2 0");

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 0 0 0");

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 3 48 0");

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 0 2 0");

Runtime.getRuntime().exec("sendevent /dev/input/"+deviceTouchEvent+" 0 0 0");

} catch (IOException e) {

// TODO Auto-generated catch block

Log.i("", "ActivityManager test User click e=" + e.toString());

e.printStackTrace();

}

}

上述代码中找出event的方法可以忽略,主要在Runtim.getRunTim().exec那儿。完成一次点击,需要将上述的9条adb shell命令全部执行一次。这些命令你也可以再cmd里手动输入测试。只不过手动比较慢,点击可能会变成长按。

下面就给大家讲getevent的具体用法:

在cmd里输入命令getevent,这个时候你再去点击屏幕的时候,就会把你点击的点给记录下来。e50787330f55fbd59f83457dc52fc4c4.png

如图,我点击的是x=1b3,y=2aa的点。

看出来了吧,系统记录的是16进制的。你只需要转换一下就可以了。以第一条为例,转换完的数据是 3 57 0;

截屏;

截屏相信能够支持的也是很多,这里就介绍一个个人感觉比较好的吧。

该方法只适用于4.0以后的版本,4.0以前的版本跨进程截屏是需要JNI方法的。

直接调用我上面的RootCmd方法,输入截屏命令就可以了。

RootCmd("screencap -p "+filePath);

同模拟点击不同,模拟点击只需要获取一次root权限即可,而截屏,每次调用是都需要root的。所以直接掉封装好的RootCmd方法就可以了。

4.3貌似还有screenshot方法。这个没怎么试过。2.3的手机就别想这个方法了,截不出来的,倒是会生成一个文件,但是是一个有大小没图像的东东。目前没找到原因。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值