后台app获取屏幕点击事件

近期需要用到后台APP获取屏幕点击事件,最初的思路是用WindowManager添加一个LinearLayout,在onTouch()中log打印即可,搜索之后发现有两种实现方法

WindowManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private final void paint(){
WindowManager manager = (WindowManager) this.getSystemService(WINDOW_SERVICE);
Button layout = new Button(this);
layout.setOnTouchListener(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
1,
1,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSPARENT
);
params.gravity = Gravity.LEFT | Gravity.TOP;
manager.addView(layout, params);
}
1
2
3
4
public boolean onTouch(View view, MotionEvent motionEvent) {
Log.w("TAG",motionEvent.toString());
return false;
}

1.创建一个透明的小部件上的,这样所有的触摸事件都将在我们的小部件,小部件将不使用任何点击事件return false;,仅log打印。

2.使用window的type为WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY需添加创建系统window的权限<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>在Android6.0以上使用将会出现权限错误,需要动态注册

1
2
3
4
5
6
7
8
9
@RequiresApi(api = Build.VERSION_CODES.M)
public void getPermission() {
if (!Settings.canDrawOverlays(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 1234);
}
}

3.放入Service中,在onDestory中删除该部件

4.window的type可以为WindowManager.LayoutParams.TYPE_TOAST,不需要配置权限,仅对API19以上有效;19以下采用TYPE_PHONE

getevent

直接读取系统事件,但需要root权限。

1
2
String[] cmd = {"su", "-c", "getevent -p"};
Process p = Runtime.getRuntime().exec(cmd);

或直接在Android Studio terminal 中输入adb shell getevent - p,将得到所有事件(包括点击、滑动…)