Android simular el golpe rápido
Estoy haciendo un script de automatización genérico.
Necesito enviar eventos complejos de desplazamiento a la pantalla de Android sin tener específicamente acceso a la aplicación (s) enfocada (s)
- Android Studio no puede enlazar con local 8602 para depurador
- Ejecutar Android sin GUI (Android sin cabeza)
- Logcat para varios dispositivos que se ejecutan al mismo tiempo en Android Studio?
- Los dispositivos Adb no pueden encontrar mi teléfono
- ¿Por qué adb instala <same-packagename-always-release> falla?
La mejor manera que pensé hasta ahora es usar adb, crear un archivo con comandos sendevent, empujarlo en el dispositivo y ejecutarlo desde allí. Incluso eso, es dolorosamente lento (mucho más lento en comparación con si lo grabo con getevent y tubo de nuevo en).
Me las arreglé para optimizar el archivo ya que me di cuenta de que cada bloque sendevent no requiere específicamente X y Y, pero sigue siendo unos pocos órdenes de magnitud más lento
Ejemplo de parte del archivo (estoy probando un 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
Así que mi enfoque es optimizar la velocidad de los golpes individuales largos y complejos, no de varios pequeños.
Alguien sabe de una mejor manera de hacer esto?
Por lo tanto, la idea de Chris Stratton funcionó en principio (volver a canalizar la salida cat-ed genera el mismo golpe con éxito), pero no puedo ser capaz de crear mi propio código de tubería de nuevo pulg Im supongo que es algo que hacer Con los separadores entre los comandos de envío de eventos … pero todavía no puedo conseguir que funcione
He utilizado una modificación del archivo sendevent.c para obtener un archivo con triples por línea y salida a otro archivo. ¿Por casualidad usted sabe cuál podría ser el problema? La conversión parece buena …
SOLUCIÓN: He logrado solucionarlo, sobre todo gracias a las respuestas a continuación. Esta es una secuencia de comandos C que toma un archivo con valores HEX y genera el archivo binario apropiado.
Uso: (para mí, el archivo del controlador táctil es / dev / input / event5 – HTC One – para otros dispositivos podría ser un archivo diferente!)
$> 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"
Y la fuente:
#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; }
- Iniciar aplicación a través de adb sin saber Nombre de actividad
- Cómo utilizar un script para consultar la base de datos android sqlite
- Android ADB Shell no activa los paquetes
- Android: Detecta cuando ADB activa a través de USB
- ¿Cómo habilitar adbd para escuchar un puerto en el arranque en Android?
- Dd de android a mi computadora?
- Adb logcat cordova android 4
- La conexión a adb ha fallado y se ha producido un error grave. Debe reiniciar adb y Eclipse.Por favor, asegúrese de que adb esté correctamente ubicado
Su retraso es probablemente el resultado de ineficaz tener que lanzar repetidamente un nuevo proceso sendevent
, analizar el registro de eventos textual, y abrir el nodo de dispositivo – para cada evento individual. Si en su lugar lo hace todo desde un solo proceso, abriendo el archivo del dispositivo sólo una vez, será mucho más eficiente.
Si nos fijamos en la fuente para sendevent en caja de herramientas (por ejemplo, desde el espejo no oficial, pero navegable en https://github.com/android/platform_system_core/blob/master/toolbox/sendevent.c ) vemos que el núcleo de lo que Que está haciendo es la codificación de los eventos en los registros binarios
struct input_event { struct timeval time; __u16 type; __u16 code; __s32 value; };
Y escribirlas en el dispositivo apropiado
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));
Siempre que ejecutes algo como el userid del shell
o el otro en el grupo unix de input
, deberías ser capaz de lograr lo mismo que sendevent
hace desde tu propio programa personalizado, o usando otras herramientas de línea de comandos como cat
, de manera eficiente empujando un binario Archivo de registros de eventos.
Por ejemplo
adb shell cd /mnt/sdcard cat /dev/input/event2 > events
Hacer unos pocos eventos de pantalla táctil, luego ctrl-C para matar al gato
Ahora puede reproducir el archivo capturado de eventos binarios:
cat events > /dev/input/event2
(Nota: sendevent está poniendo a cero la parte timeval
de cada registro, la grabación y reproducción no puede hacer eso, tendrá que ver, y si importa cero esas porciones de cada registro del archivo antes de volver a escribirlo)
Si sólo desea producir desplazamientos lineales, puede utilizar input swipe
comando de input swipe
en shell.
$ adb shell input usage: input ... input text <string> input keyevent <key code number or name> input [touchscreen|touchpad|touchnavigation] tap <x> <y> input [touchscreen|touchpad|touchnavigation] swipe <x1> <y1> <x2> <y2> [duration(ms)] input trackball press input trackball roll <dx> <dy>
El comando abajo dibuja una línea agradable para mí en una aplicación de dibujo
$ adb shell input swipe 300 300 500 1000
Y una más rápida
$ adb shell input touchscreen swipe 300 300 500 1000 100
- Cómo obtener el nombre de la calle del objeto Dirección / Ubicación en Android
- Cómo encontrar elemento en Ver por coordenadas x, y Android