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();
}
注意:該方式必須跑在子線程裡面,不能跑在主線程裡面。