我正在做一个通用的自动化脚本。

我需要将复杂的滑动事件发送到android屏幕,而无需专门访问已聚焦的应用程序

到目前为止,我认为最好的方法是使用adb,使用sendevent命令创建文件,将其推送到设备上并从那里运行它。即使那样,它的速度也很慢(比起我用getevent记录并通过管道将其返回)要慢得多。

我设法优化了文件,因为我发现每个sendevent块并不需要X和Y,但是它仍然慢了几个数量级

文件一部分的示例(我正在尝试使用HTC One):

sendevent /dev/input/event5 3 57 49
sendevent /dev/input/event5 3 53 942
sendevent /dev/input/event5 3 54 2747
sendevent /dev/input/event5 0 0 0

sendevent /dev/input/event5 3 53 1207
sendevent /dev/input/event5 3 54 2483
sendevent /dev/input/event5 0 0 0

sendevent /dev/input/event5 3 53 1472
sendevent /dev/input/event5 0 0 0

sendevent /dev/input/event5 3 54 2218
sendevent /dev/input/event5 0 0 0

sendevent /dev/input/event5 3 53 1207
sendevent /dev/input/event5 3 54 2483
sendevent /dev/input/event5 0 0 0

sendevent /dev/input/event5 3 53 1472

因此,我的重点是优化单个长复杂刷卡的速度,而不是多个小刷卡的速度。

有人知道有更好的方法吗?

因此,克里斯·斯特拉顿(Chris Stratton)的想法在原则上是可行的(重新管道输入cated的输出会成功生成相同的滑动),但是我无法创建自己的代码以将其通过管道传输回去。我猜这是需要做的事情与发送事件命令之间的分隔符...但我仍然无法使它正常工作

我对sendevent.c文件进行了修改,以获取每行三倍的文件并将其输出到另一个文件。您碰巧知道可能是什么问题吗?转换看起来不错...

解决:我设法解决了这个问题,这主要归功于下面的答案。这是一个C脚本,它将带有HEX值的文件并输出适当的二进制文件。

用法:(对我而言,触摸驱动程序文件为/dev/input/event5-HTC One-对于其他设备,它可能是不同的文件!!!)
 $> adb shell getevent > tmp.in
 $> ./sendevent tmp.in tmp.out
 $> adb shell push tmp.out /mnt/sdcard/
 $> adb shell "cd /mnt/sdcard/ && cat tmp.out > /dev/input/event5"

以及来源:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <errno.h>

typedef uint32_t        __u32;
typedef uint16_t        __u16;
typedef __signed__ int  __s32;

__attribute__((aligned(1),packed)) struct input_event {
    __u32 time_dummy_1;
    __u32 time_dummy_2;
    __u16 type;
    __u16 code;
    __s32 value;
};

int convert (char * str) {
    return (int) strtol(str, NULL, 16);
}

#define S_ALL (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH)

int main (int argc, char *argv[]) {
    int i;
    int fd;
    int ret;

    if(argc < 3) {
        fprintf(stderr, "use: %s in-file out-file\n", argv[0]);
        return 1;
    }

    fd = open(argv[2], O_CREAT | O_WRONLY, S_ALL);
    if(fd < 0) {
        fprintf(stderr, "could not open %s, %s\n", argv[2], strerror(errno));
        return 1;
    }

    FILE * fd_in = fopen(argv[1], "r");
    if (fd_in == NULL) {
        fprintf(stderr, "Can't open input file: %s\n", argv[1]);
        return 1;
    }

    struct input_event event;
    char type[32];
    char code[32];
    char value[32];
    int count = 0;
    while (fscanf(fd_in, "%s %s %s", type, code, value) != EOF) {
        memset(&event, 0, sizeof(event));
        // printf("%d) %s %s %s\n", ++count, type, code, value);
        event.type = convert(type);
        event.code = convert(code);
        event.value = convert(value);
        memset(type, 0, sizeof(type));
        memset(code, 0, sizeof(code));
        memset(value, 0, sizeof(value));
        ret = write(fd, &event, sizeof(event));
        if(ret < sizeof(event)) {
            fprintf(stderr, "write event failed, %s\n", strerror(errno));
            return -1;
        }
    }

    return 0;
}

最佳答案

请注意,此答案与大约2013年的Android版本有关,可能不适用于当前版本。水母当时是当代的,问问题几周后,奇巧(Kitkat)就出来了

您的延迟很可能是由于效率低下而不得不反复启动新的sendevent进程,解析文本事件记录并打开设备节点的原因-每个事件都是如此。如果您只用一个进程执行所有操作,而只打开设备文件一次,则效率会大大提高。

如果我们在当代的工具箱中使用问题的日期(例如https://android.googlesource.com/platform/system/core/+/jb-release/toolbox/sendevent.c)查看sendevent的来源,我们会发现其工作的核心是将事件编码为二进制记录

struct input_event {
    struct timeval time;
    __u16 type;
    __u16 code;
    __s32 value;
};

并将它们写入适当的设备
memset(&event, 0, sizeof(event));
event.type = atoi(argv[2]);
event.code = atoi(argv[3]);
event.value = atoi(argv[4]);
ret = write(fd, &event, sizeof(event));

假设您以shell用户ID或input unix组中的其他用户身份执行某些操作,则您应该能够通过自己的自定义程序或使用其他命令行工具(例如sendevent)来完成cat的操作,从而有效地推送事件记录的二进制文件。

例如
adb shell
cd /mnt/sdcard
cat /dev/input/event2 > events

做一些触摸屏事件,然后按Ctrl-C杀死猫

现在,您可以播放捕获的二进制事件文件:
cat events > /dev/input/event2

(注意:sendevent将每个记录的timeval部分清零;记录和回放可能不会这样做;您必须先查看一下,如果将文件中每个记录的这些部分清零,则在将其写回之前)

关于Android模拟快速滑动,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19063057/

10-10 10:36