【发布时间】:2013-09-28 03:55:45
【问题描述】:
我正在做一个通用的自动化脚本。
我需要将复杂的滑动事件发送到 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 的想法在原则上是有效的(重新对 cat-ed 输出进行管道化会成功生成相同的滑动),但我无法创建自己的代码来将其重新输入。我猜是与发送事件命令之间的分隔符有关......但我仍然无法让它工作
我使用了 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;
}
【问题讨论】:
-
我知道这是一个老问题,但你能解释一下如何把这个新的 sendevents.c 文件放到安卓设备上吗,我想你会使用 adb push 但不知道我在哪个目录可以放置文件,使其成为可执行文件。
-
我现在创建了一个更合适的问题。您的帮助将不胜感激。 stackoverflow.com/questions/23131081/…
-
我发布了您问题的答案。希望对您有所帮助:stackoverflow.com/questions/23131081/…