android模拟点击
模拟点击两套方案:
1、使用Instrumentation
new Thread(() -> {
Instrumentation inst = new Instrumentation();
long curTime = SystemClock.uptimeMillis();
inst.sendPointerSync(MotionEvent.obtain(curTime, curTime,
MotionEvent.ACTION_DOWN, otr.x, otr.y, 0));
inst.sendPointerSync(MotionEvent.obtain(curTime, curTime,
MotionEvent.ACTION_UP, otr.x, otr.y, 0));
}).start();
问题:应用内界面没有问题,能正常触发点击效果
但是在应用外的界面(当前应用后台运行,在其他应用界面),比如系统设置的界面,出现的是长按的效果。如下视频。
2024-10-29-15-58-43_模拟点击异常_哔哩哔哩_bilibili
2、用adb模拟点击
input tap x y
。。。。。。
new Thread(() -> {
String cmd = "input tap " + otr.x + " " + otr.y;
Log.d(TAG, "forceClick cmd: " + cmd);
CmdUtils.fetchRoot(cmd);
}).start();
。。。。。。
// CmdUtils.java
package com.example.helloworld.utils;
import android.util.Log;
import java.io.DataOutputStream;
import java.io.IOException;
public class CmdUtils {
public static String execRootCmd(String cmd) {
String content = "";
cmd = cmd.replace("adb shell", "");
//先获取root权限
// fetchRootCmd();
try {
Process process = Runtime.getRuntime().exec(cmd);
Log.d("Main", "process " + process.toString());
content = process.toString();
} catch (IOException e) {
Log.d("Main", "exception " + e.toString());
return e.getMessage();
}
return content;
}
public static void fetchRoot(String cmd){
try {
Process ps = Runtime.getRuntime().exec("su"); //1、执行su切换到root权限
Log.d("Main", "fetchRoot: " + ps.toString());
DataOutputStream dos = new DataOutputStream(ps.getOutputStream());
dos.writeBytes(cmd + "\n"); // 2、向进程内写入shell指令,cmd为要执行的shell命令字符串
dos.flush();
dos.close();
ps.waitFor();
} catch (IOException | InterruptedException e) {
Log.e("TAG", "fetchRootError: "+ e.getMessage() );
}
}
}
这个写法,因为fetchroot里使用root权限,所以需要系统签名。
note:
这两个写法都使用了new Thread(() -> {}).start()写法,因为不这样,会触发运行崩溃。