EDIT: Below you can find a way to use sendevent, however as I figured since posting, sendevent
will not work on later Android devices, as access to input devices from shell has been explicitely disabled in SELinux policy. I don't know a way to work around this without rooting. The recommended way is to use UiAutomation#injectInputEvent
. That's Java code, so one could write a service, which forwards events received on some interface. That leads far way beyond this question. Anyway, my sendevent solution you may still use on some devices.
You can find complete sendevent
examples online (eg in this blog post), but none worked for me out of the box, so I had to tweak things a bit.
First of all, if you want to use sendevent
, you should figure out the right event device first. getevent
can be used to obtain this info, either getevent -p
or getevent -i
will tell you the event dev <-> device connections, so you can find the event associated with your touchscreen device.
You can also use getevent
to see how a real tap event looks like on your device. Just run adb shell
, start getevent
, then tap on the screen (for some reason adb shell getevent
didn't return the events):
/dev/input/event2: 0003 0039 000025e9
/dev/input/event2: 0001 014a 00000001
/dev/input/event2: 0003 0035 00000320
/dev/input/event2: 0003 0036 000002ae
/dev/input/event2: 0000 0000 00000000
/dev/input/event2: 0003 0030 00000005
/dev/input/event2: 0000 0000 00000000
/dev/input/event2: 0003 0039 ffffffff
/dev/input/event2: 0001 014a 00000000
/dev/input/event2: 0000 0000 00000000
You get a bunch of hex codes. Try the same with getevent -l
:
/dev/input/event2: EV_ABS ABS_MT_TRACKING_ID 000025e8
/dev/input/event2: EV_KEY BTN_TOUCH DOWN
/dev/input/event2: EV_ABS ABS_MT_POSITION_X 000002f8
/dev/input/event2: EV_ABS ABS_MT_POSITION_Y 000002f2
/dev/input/event2: EV_ABS ABS_MT_TOUCH_MAJOR 00000005
/dev/input/event2: EV_ABS ABS_MT_TOUCH_MINOR 00000004
/dev/input/event2: EV_SYN SYN_REPORT 00000000
/dev/input/event2: EV_ABS ABS_MT_TRACKING_ID ffffffff
/dev/input/event2: EV_KEY BTN_TOUCH UP
/dev/input/event2: EV_SYN SYN_REPORT 00000000
and you will see the labels for the codes (where applicable), so you can match the codes with the labels. If you don't want a generic solution, just want it to work on your own device, then you only have to recreate the tap sequence you've just seen. (Be careful with the hex codes, getevent prints hex, but sendevent expects decimal.)
This is the code I use in one of my scripts:
EV_SYN=0
EV_KEY=1
EV_ABS=3
BTN_TOUCH=330
BTN_TOUCH_DOWN=1
BTN_TOUCH_UP=0
SYN_REPORT=0
ABS_MT_TRACKING_ID=57
ABS_MT_POSITION_X=53
ABS_MT_POSITION_Y=54
ABS_MT_TOUCH_MAJOR=48
ABS_MT_TOUCH_MINOR=49
event_dev=`adb shell getevent -pl 2>/dev/null | sed -e ':a;N;$!ba;s/\n / /g' | awk '/ABS_MT_TOUCH/{print \$4}'`
tracking_id=1111
POS_X=600
POS_Y=800
adb shell "
sendevent $event_dev $EV_ABS $ABS_MT_TRACKING_ID $tracking_id
sendevent $event_dev $EV_KEY $BTN_TOUCH $BTN_TOUCH_DOWN
sendevent $event_dev $EV_ABS $ABS_MT_POSITION_X $POS_X
sendevent $event_dev $EV_ABS $ABS_MT_POSITION_Y $POS_Y
sendevent $event_dev $EV_ABS $ABS_MT_TOUCH_MAJOR 5
sendevent $event_dev $EV_ABS $ABS_MT_TOUCH_MINOR 4
sendevent $event_dev $EV_SYN $SYN_REPORT 0
"
adb shell "
sendevent $event_dev $EV_ABS $ABS_MT_TRACKING_ID -1
sendevent $event_dev $EV_KEY $BTN_TOUCH $BTN_TOUCH_UP
sendevent $event_dev $EV_SYN $SYN_REPORT 0
"
It works on my non-rooted device, but you may have to tweak it to match your device codes and sequences.
input
is slow.