首页
社区
课程
招聘
3
[原创]通过sendevent实现多点连续滑动
发表于: 2019-6-18 17:31 11397

[原创]通过sendevent实现多点连续滑动

2019-6-18 17:31
11397

最近在瞎琢磨Android设备的云控,想要实现一个多点滑动的功能。我们知道通过shell执行input swipe x1 y1 x2 y2 t可以实现t毫秒内从坐标(x1, y1)滑动到(x2, y2),滑动完成后模拟的动作就“被抬起”,很难直接通过input实现滑动”转弯“。于是花了半天时间看了一下sendevent的参数含义,简单实现了连续滑动的功能。

sendevent需要4个参数,如下:
use: sendevent device type code value
含义分别是设备、事件类型、事件代码以及传递的数据。
在分析之前可以通过getevent获取事件的数据以便参照,如下为简单滑动后获取的数据:

type和code的含义可参照内核源码中的input.h,笔者用的Nexus6P,msm-android-msm-angler-3.10-nougat-mr2,该头文件位于include/uapi/linux/input.h。

滑动所需的type含义如下:

type 0000 Synchronization events
type 0001 Keys and buttons
type 0003 Absolute axes,即描述运动事件的值

code含义如下

0000 0000 SYN_REPORT,这里笔者简单理解为与io的flush类似
0003 0039 开始接触设备的唯一标识号,这里为0xc3a, 0xffffffff代表结束接触
0001 014a 标明触摸事件,1代表按下,0代表放开
0001 0145 表明是用手指触摸的,同样1代表按下,0代表放开
0003 0035 触摸的x坐标
0003 0036 触摸的y坐标
0003 0030 接触面椭圆长轴,非必需
0003 0031 接触面椭圆短轴,非必需

其实到这里已经很清晰了,开始接触->按下->一系列坐标移动->结束接触->放开,通过坐标的移动可以控制滑动的痕迹,sendevent执行的快慢控制滑动的快慢。要注意最好执行在同一个shell,并且不要阻塞(waitfor)。
给出的代码直接调用即可:

即从(357, 2054)滑动到(1112, 1308),接着又滑到(1112, 2032)。代码写得很粗糙。

如果需要改变滑动的速度,可以将代码里控制坐标间隔次数的值SWIPE_RUN_INTERVAL改小一点,间隔次数越少,滑动越快。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2019-11-20 10:02 被Umiade编辑 ,原因:
上传的附件:
收藏
免费 3
支持
分享
赞赏记录
参与人
雪币
留言
时间
naihes
为你点赞~
2023-11-28 19:52
PLEBFE
为你点赞~
2023-1-25 03:23
Umiade
为你点赞~
2019-11-19 14:18
最新回复 (10)
雪    币: 2907
活跃值: (1376)
能力值: ( LV12,RANK:215 )
在线值:
发帖
回帖
粉丝
2
2019-6-19 13:21
0
雪    币: 465
活跃值: (564)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢楼主。
2019-6-19 13:48
0
雪    币: 2484
活跃值: (3262)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
谢谢
2019-11-19 14:21
0
雪    币: 2484
活跃值: (3262)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
雨天不带鱼 谢谢
为啥滑动的时候会停顿一下然后继续滑动、好像不太流畅。是因为shell的问题?
2019-11-19 20:22
0
雪    币: 4100
活跃值: (2454)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
雨天不带鱼 为啥滑动的时候会停顿一下然后继续滑动、好像不太流畅。是因为shell的问题?

之前测试的时候影响速度的一个是shell,一个是移动坐标间隔的次数
shell就是我上面说的用同一个进程,直接将命令写入流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public static Process nonBlockShell;
public static DataOutputStream nonBlockOutputStream;
 
public static BufferedReader nonBlockSuccessResult = null;
public static BufferedReader nonBlockErrorResult = null;
 
static {
    initNonBlockShell();
}
 
public static int initNonBlockShell() {
    try {
        nonBlockShell = Runtime.getRuntime().exec("su");
        nonBlockOutputStream = new DataOutputStream(nonBlockShell.getOutputStream());
        nonBlockSuccessResult = new BufferedReader(new InputStreamReader(nonBlockShell.getInputStream()));
        nonBlockErrorResult = new BufferedReader(new InputStreamReader(nonBlockShell.getErrorStream()));
        readNonBlockStream();
    } catch (Throwable e) {
        e.printStackTrace();
        return -1;
    }
    return 0;
}
 
public static void readNonBlockStream() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                while (nonBlockSuccessResult != null) {
 
                    String s;
                    while ((s = nonBlockSuccessResult.readLine()) != null) {
                        Logger.i("[<< EXEC SUCCESS]" + s);
                    }
                }
            } catch (Exception e) {
                Logger.e("read nonBlockSuccessResult error:", e);
            }
        }
    }).start();
 
 
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                while (nonBlockErrorResult != null) {
                    String e;
                    while ((e = nonBlockErrorResult.readLine()) != null) {
                        Logger.e("[<< EXEC ERROR]" + e);
                    }
                }
            } catch (Exception e) {
                Logger.e("read nonBlockErrorResult error:", e);
            }
        }
    }).start();
 
}
 
public static int execNonBlockRootCmd(String cmd) {
    int ret = 0;
    if (null == nonBlockShell || null == nonBlockOutputStream) {
        if (initNonBlockShell() < 0) {
            Logger.e("execNonBlockRootCmd getRuntime for su error!");
            return -1;
        }
    }
    Logger.d("[>>]" + cmd);
    try {
        nonBlockOutputStream.writeBytes(cmd + "\n");
        nonBlockOutputStream.flush();
 
    } catch (Exception e) {
        Logger.e("execNonBlockRootCmd error:", e);
        ret = -1;
    }
    return ret;
}

至于坐标之间的间隔,将上面代码里面SWIPE_RUN_INTERVAL改小一点,可以明显提高滑动速度。

2019-11-20 09:54
0
雪    币: 2484
活跃值: (3262)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
Umiade 之前测试的时候影响速度的一个是shell,一个是移动坐标间隔的次数 shell就是我上面说的用同一个进程,直接将命令写入流 ``` public static Process nonBlock ...
好的、我试试!谢谢!
2019-11-20 10:10
0
雪    币: 1387
活跃值: (5614)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
8
能用不?,听说发送要把,16进制改成10进制?
2019-11-21 10:59
0
雪    币: 4100
活跃值: (2454)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
supperlitt 能用不?,听说发送要把,16进制改成10进制?
都用字符串写入流了默认当然是十进制的
2019-11-21 13:53
0
雪    币: 2484
活跃值: (3262)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
supperlitt 能用不?,听说发送要把,16进制改成10进制?
可以使用、项目已经跑起来了 很不错的!
2019-11-21 18:30
0
雪    币: 266
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gqm
11
老兄可以找你定做个这 控制器吗?
2019-12-16 18:28
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册