Emulating touchscreen interaction with sendevent in Android

Android provides these two convenient tools for dealing with input events:

getevent

for dumping input events and providing information about input devices

sendevent - for injecting input events

Every sendevent command requires 4 parameters:
device_name (string)
event_type (decimal int)
event_code (decimal int)
value (decimal int)

First you need to find the name of touchscreen device.
in adb

getevent -p

get the event list
Let's assume it printed out "/dev/input/event0" - this would be the first parameter.

For touch events only 2 event types are used:
EV_ABS (3)
EV_SYN (0)

Touching the display (in case of Type A protocol) will result in an input report (sequence of input events) containing the following event codes:
ABS_MT_TRACKING_ID (57) - ID of the touch (important for multi-touch reports)
ABS_MT_POSITION_X (53) - x coordinate of the touch
ABS_MT_POSITION_Y (54) - y coordinate of the touch
ABS_MT_TOUCH_MAJOR (48) - basically width of your finger tip in pixels
ABS_MT_PRESSURE (58) - pressure of the touch
SYN_MT_REPORT (2) - end of separate touch data
SYN_REPORT (0) - end of report

Let's say we want to emulate a touch down event at the point with coordinates x=300, y=400. We will need to execute the following sendevent commands:

sendevent /dev/input/event0 3 57 0
sendevent /dev/input/event0 3 53 300
sendevent /dev/input/event0 3 54 400
sendevent /dev/input/event0 3 48 5
sendevent /dev/input/event0 3 58 50
sendevent /dev/input/event0 0 2 0
sendevent /dev/input/event0 0 0 0

I used arbitrary values of 5 for the ABS_MT_TOUCH_MAJOR (makes for very small finger tip for high precision) and 50 for the ABS_MT_PRESSURE (a slight tap) which work good enough for most applications.

For most touch screens on the market it takes 20 to 50 milliseconds to reliably register the touch. So I would recommend to wait at least 50 milliseconds before sending the release event report. If you want to emulate the long touch - then you wait longer. You can use busybox usleep command:

busybox usleep 50000

The release report is really simple. To let the input device know that all previous touches have been released - you just send the empty report with ABS_MT_TRACKING_ID = -1:

ABS_MT_TRACKING_ID (57)
SYN_MT_REPORT (2)
SYN_REPORT (0)

sendevent /dev/input/event0 3 57 -1 `
sendevent /dev/input/event0 0 2 0
sendevent /dev/input/event0 0 0 0

This is how injecting touch events could be implemented in python:

#!/usr/bin/python

import subprocess
import os

def adbshell(command, serial=None, adbpath='adb'):
    args = [adbpath]
    if serial is not None:
        args.append('-s')
        args.append(serial)
    args.append('shell')
    args.append(command)
    return os.linesep.join(subprocess.check_output(args).split('\r\n')[0:-1])

def adbdevices(adbpath='adb'):
return [dev.split('\t')[0] for dev in subprocess.check_output([adbpath, 'devices']).splitlines() if dev.endswith('\tdevice')]

def touchscreen_devices(serial=None, adbpath='adb'):
return [dev.splitlines()[0].split()[-1] for dev in adbshell('getevent -il', serial, adbpath).split('add device ') if dev.find('ABS_MT_POSITION_X') > -1]

def tap(devicename, x, y, serial=None, adbpath='adb'):
adbshell('S="sendevent {}";$S 3 57 0;$S 3 53 {};$S 3 54 {};$S 3 58 50;$S 3 50 5;$S 0 2 0;$S 0 0 0;'.format(devicename, x, y), serial, adbpath)
adbshell('S="sendevent {}";$S 3 57 -1;$S 0 2 0;$S 0 0 0;'.format(devicename), serial, adbpath)

serial = adbdevices()[0]
touchdev = touchscreen_devices(serial)[0]
tap(touchdev, 100, 100, serial)

view rawtouch_test.py hosted with ❤ by GitHub
Labels: adb, android, busybox, getevent, sendevent
2 comments:

NavigatorJuly 5, 2013 at 4:43 AM
At least on my Motorola Defy with CM7 (Android 2.3.7) things look a bit different.
It looks like
0 2 0
0 0 0
is NOT a release report, but some kind of activation of the previous sendevent commands.
To release you have to send an additional command (including activation):

sendevent /dev/input/event3 3 57 -1
sendevent /dev/input/event3 0 2 0
sendevent /dev/input/event3 0 0 0
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容

  • 从前是世界一片黑暗,宇宙中有一个大鸡蛋,大鸡蛋里面有个人,那就是盘古,他睡了1800年。突然有一天他醒来了,他什么...
    谢孟佳阅读 268评论 0 1
  • 今天下午刷微博的时候,看到漫画家陈缘风的微博,晒着各种跟女儿蓝蓝的腻歪又温馨的日常。突然,好想找个这样的蓝银结婚,...
    WHelen阅读 911评论 9 18
  • 今天周三对班有个同事休班,今天下午我们早班开完宾 然后准备下班的时候对班的队长去吃饭了 只剩下店长一个人了,担心店...
    kyle房成阅读 262评论 8 0
  • 好累。 每天装卸货,像劳务一样,赚着寥寥无几的薪水,手上磨了个水泡,胳膊被蹭出来好多伤痕,没有人关心,没有人心疼,...
    大白比小白白阅读 420评论 2 0