How to perform a swipe with 'duration' using sendevent and adb

Viewed 700

I'm using the code above to simulate a 'swipe' using sendevent:

sendevent /dev/input/event0 3 53 300 ;First position X
sendevent /dev/input/event0 3 54 600 ;First position Y
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

sendevent /dev/input/event0 3 53 300  ;Second position X
sendevent /dev/input/event0 3 54 400  ;Second position Y
sendevent /dev/input/event0 0 2 0
sendevent /dev/input/event0 0 0 0

sendevent /dev/input/event0 0 2 0
sendevent /dev/input/event0 0 0 0

However, it does swipe instantly without any delay.

I'm trying to figure how to specify the duration of the swipe, like you can do using adb shell input:

input [touchscreen|touchpad|touchnavigation] swipe <x1> <y1> <x2> <y2> [duration(ms)]

shell input swipe 300 400 300 200 2000

This produces a swipe with a duration of 2 seconds.

I have tried to add a sleep 2 before the ;Second position but it does result in a pause before the swipe instead of a swipe with 2 seconds of duration.

With duration I mean, the time slowly swapping from position 1 to position 2.

3 Answers

The problem with this is that sending events through sendevent takes some time. I made a python script (You can take whatever you need from there) that interpolates points between the given ones. It also waits some time between points.

This is the lineal interpolation code:

def lerp(p1:tuple, p2:tuple, points:int) -> list:
    output = []
    header = [_p2 - _p1 for _p1, _p2 in zip(p1, p2)]
    for p in range(points + 1):
        percent = p / points
        output.append((p1[0] + percent * header[0], p1[1] + percent * header[1]))
    return output

The time problem appears when using multiples points. Using a path with 10 interpolated points with no time between them already takes 1.29 seconds and a 100 points one, 11.45.

If you compare the sendevent and input commands' source code you can clearly understand their goals; the former covers basic command line's input events whereas the latter covers more flexible and complex input scenarios.

To get an insight on how the swipe duration has been implemented (on input command) you can focus directly on the sendSwipe method: it sends multiple basic input events, leveraging the InputManager, in a timespan defined by the duration parameter

final long endTime = down + duration;

The function injectMotionEvent used by sendSwipe doesn't have any concept of "duration".

That said, I think the command you're looking for, as of today, doesn't exist and I believe you can still rely on console prompt like

input swipe 300 400 300 200 2000

that can be invoked after using

adb shell

One cannot set the duration on the low level, but one can record analog input and then play it back. This permits for more flexible and complex scenarios ...because the events are countless.


Run adb shell to open a shell.

Where ...

  • getevent --help shows all available options.
  • getevent -p shows all recordable devices.
  • getevent -lp /dev/input/event1 shows BTN_TOUCH event data format.
  • getevent /dev/input/event1 logs input events for device focaltech_ts.
  • getevent -l /dev/input/event1 is human-readable (useless for automation).

To record:

  • cd sdcard/Download
  • getevent /dev/input/event1 >> ./swipe.log
  • download swipe.log with the Android device explorer.

Where 0003 means coordinate, and 0x35 is the X-axis and 0x36 is the Y-axis:

0003 0035 000001a8
0003 0036 000005cb

This log can the be played back by a shell script loop, with sendevent.
sendevent --help shows the expected parameters: DEVICE TYPE CODE VALUE.

cat ./swipe.log | while read line 
do
    adb shell sendevent /dev/input/event1 $line
done

When delaying the execution with sleep, the lines with 0000 0000 00000000 might suit best.


Alike this one can also automate GPIO buttons, which maybe be quite specific on certain devices. UiObject2.swipe() might also just generate linear-interpolation coordinates and play them back. It generally does not matter, if they're generated or recorded - the only difference is that the one movement is perfectly straight and the other one obviously isn't.

Related