Использовать /dev/uinput для имитации сенсорного события в Android не работает
Я пытаюсь использовать / dev / uinput для имитации сенсорного события в Android, такой код:
сначала откройте файл "/ dev / uinput" и создайте udev:
static int open_uinput_device(){
uinp_fd = open(uinput_deivce_path, O_WRONLY | O_NDELAY);
if (uinp_fd <= 0) {
debug("could not open %s, %s", uinput_deivce_path, strerror(errno));
return -1;
}
memset(&ui_dev, 0, sizeof(ui_dev));
strncpy(ui_dev.name, "RemoteTV Event", UINPUT_MAX_NAME_SIZE);
ui_dev.id.bustype = BUS_USB;
ui_dev.id.vendor = 0x1341;
ui_dev.id.product = 0x0001;
ui_dev.id.version = 4;
ui_dev.absmin[ABS_MT_SLOT] = 0;
ui_dev.absmax[ABS_MT_SLOT] = 9;
ui_dev.absmin[ABS_MT_TOUCH_MAJOR] = 0;
ui_dev.absmax[ABS_MT_TOUCH_MAJOR] = 255;
ui_dev.absmin[ABS_MT_POSITION_X] = 0;
ui_dev.absmax[ABS_MT_POSITION_X] = screen_width - 1;
ui_dev.absmin[ABS_MT_POSITION_Y] = 0;
ui_dev.absmax[ABS_MT_POSITION_Y] = screen_Height - 1;
ui_dev.absmin[ABS_MT_TRACKING_ID] = 0;
ui_dev.absmax[ABS_MT_TRACKING_ID] = 65535;
ui_dev.absmin[ABS_MT_PRESSURE] = 0;
ui_dev.absmax[ABS_MT_PRESSURE] = 30;
ui_dev.absmin[ABS_MT_TOOL_TYPE] = 0;
ui_dev.absmax[ABS_MT_TOOL_TYPE] = 1;
//enable direct
ioctl(uinp_fd, UI_SET_PROPBIT, INPUT_PROP_DIRECT);
//enable mouse event
ioctl(uinp_fd, UI_SET_EVBIT, EV_REL);
ioctl(uinp_fd, UI_SET_RELBIT, REL_X);
ioctl(uinp_fd, UI_SET_RELBIT, REL_Y);
//enable touch event
ioctl(uinp_fd, UI_SET_EVBIT, EV_ABS);
for (i = 0; i <= ABS_CNT; i++) {
ioctl(uinp_fd, UI_SET_ABSBIT, i);
}
ioctl(uinp_fd, UI_SET_EVBIT, EV_SYN);
ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
for (i = 0; i < 256; i++) {
ioctl(uinp_fd, UI_SET_KEYBIT, i);
}
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_TOUCH);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MIDDLE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_FORWARD);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_BACK);
write(uinp_fd, &ui_dev, sizeof(ui_dev));
if (ioctl(uinp_fd, UI_DEV_CREATE)) {
debug("Unable to create UINPUT device.");
return -1;
}
return 0;
}
и затем напишите некоторые события в uinput_fd, сегмент кода, подобный этому:
int len;
// Move pointer to (100,100) location
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = type;
event.code = code;
event.value = value;
len = write(uinp_fd, &event, sizeof(event));
debug("SendEventToUinput done:%d %d %d",type, code, value);
Я могу видеть события, записанные в /dev/input/event7 в терминале, введя команду "getevent -l", например так:
/dev/input/event7: EV_KEY BTN_TOUCH DOWN /dev/input/event7: EV_ABS ABS_MT_TRACKING_ID 00000027 /dev/input/event7: EV_ABS ABS_MT_TOUCH_MAJOR 0000005d /dev/input/event7: EV_ABS ABS_MT_POSITION_X 00000251 /dev/input/event7: EV_ABS ABS_MT_POSITION_Y 0000048f /dev/input/event7: EV_SYN SYN_REPORT 00000000 /dev/input/event7: EV_ABS ABS_MT_TOUCH_MAJOR 00000045 /dev/input/event7: EV_SYN SYN_REPORT 00000000 /dev/input/event7: EV_ABS ABS_MT_TRACKING_ID ffffffff /dev/input/event7: EV_SYN SYN_REPORT 00000000 /dev/input/event7: EV_KEY BTN_TOUCH UP /dev/input/event7: EV_SYN SYN_REPORT 00000000
но ничего не показывать на экране, если я отправляю те же события на "dev/input/event4", это может работать? почему "dev / uinput" является недействительным?
Кто-нибудь, помогите мне, пожалуйста.
4 ответа
Когда вы выполните эту часть:
ioctl(uinp_fd, UI_SET_EVBIT, EV_ABS);
for (i = 0; i <= ABS_CNT; i++) {
ioctl(uinp_fd, UI_SET_ABSBIT, i);
}
Вы также устанавливаете биты ABS_X и ABS_Y. Биты ABS_X и ABS_Y не должны устанавливаться вместе с битами ABS_MT_POSITION_X и ABS_MT_POSITION_Y.
Я предлагаю только установить биты ABS, которые вы будете использовать.
Ваше имя ui_dev.name уже существует, используйте другое, и оно будет работать нормально.
Рассмотрение реализации ввода оболочки adb:https://android.googlesource.com/platform/frameworks/base/+/HEAD/cmds/input/src/com/android/commands/input/Input.java Существуют преобразования типов координаты. Может быть, поэтому одни и те же координаты, отправленные во входное событие, переводятся в разные координаты при захвате с помощью adb shell getevent. У меня до сих пор нет решения, но эта информация может оказаться полезной для вас - чтобы координаты не переводились, необходимо ввести их на уровне AOSP в плавающей форме. - батцилла
Попробуйте изменить последовательность назначения аргументов в:
strncpy(ui_dev.name, "RemoteTV Event", UINPUT_MAX_NAME_SIZE);
сделай это:
strncpy(ui_dev.name, UINPUT_MAX_NAME_SIZE, "RemoteTV Event");
В моем pionion, вы должны использовать командную строку ADB, как это:
adb shell sendevent /dev/input/event[event_number_here] input_value_here
например:
adb shell sendevent /dev/input/event2 1 315 1
adb shell sendevent /dev/input/event2 0 0 0
или вы можете попробовать эту команду:
adb shell input tap x y
например: входной сигнал обоймы adb 150 150