Android 模拟点击
前言
最近提出一个需求让做模拟点击,什么意思呢?就是有一个按钮,你点击这个按钮触发的不是按钮本身,而是其他的地方。其实就是在用户不触摸手机屏幕的时候,模拟触发手机屏幕的某个地方。
不知道大家平时开发的过程用到的 adb shell命令 的地方多不多呢?
今天这个需求,我们就用adb shell命令 来完成。
真机实验
我们先用USB连接真机,在cmd命令行工具里:
adb shell
[email protected]:/ $ input tap 125 521
[email protected]:/ $
这里的意思就是点击屏幕上 (x, y) = (125, 521)的地方。果然手机响应了,缺点就是响应时间略长,感觉有1秒左右。
同理其他手势操作也可以完成,这里不作详解,感兴趣的可以自行搜索。
下面我们需要做的就是在代码里完成上述操作,并且可以持续在后台运行。这里我也是踩坑无数,听我慢慢吐槽
方式一 ProcessBuilder
直接上代码:
/**
* 传入在屏幕中的坐标,坐标左上角为基准
* 模拟点击
*
* @param x 需要点击的x坐标
* @param y 需要点击的y坐标
*/
public static void autoClickPos(final double x, final double y) {
new Thread(new Runnable() {
@Override
public void run() {
// 利用ProcessBuilder执行shell命令
String[] order = {"input", "tap", "" + x, "" + y};
try {
new ProcessBuilder(order).start();
LogUtil.e("命令执行了");
} catch (IOException e) {
e.printStackTrace();
LogUtil.e("命令执行了,但是出错啦");
}
}
}).start();
}
方式二:Instrumentation
/**
* 传入在屏幕中的坐标,坐标左上角为基准
* 模拟点击
*
* @param x 需要点击的x坐标
* @param y 需要点击的y坐标
*/
public static void onStartClickView(final float x, final float y) {
new Thread(new Runnable() {
@Override
public void run() {
try {
Instrumentation inst = new Instrumentation();
inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0));
inst.sendPointerSync(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0));
LogUtil.i("模拟点击" + x + ", " + y);
} catch (Exception e) {
LogUtil.e(e.toString());
}
}
}).start();
}
注意:该方式必须跑在子线程里面,不能跑在主线程里面。