'Why is sendevent freezing?
I have been working very hard to find how to emulate tap with sendevent to be able to use very precise swipes. I just succeed to make a tap using this code shared down below in stackoverflow.
Surprisingly, the tap is execute but just the "finger down" order....it stay like this untill i move my mouse over the emulator windows.
What Am I missing ??
from ppadb.client import Client
def lerp(p1: tuple, p2: tuple, points: int) -> list:
'''
Creates a list of points with len = points between p1 and p2 using lineal interpolation
:param p1: First point.
:param p2: Second point.
:param points: Number of points in between.
'''
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
class AdbInput:
"""
Sends input events to a given adb device using ppadb and the sendevent shell command.
"""
def __init__(self, client: Client, device: int = 0, eventId: int = 6):
'''
Creates an AdbInput object able to send inputs to an adb device
:param client: The adb client.
:param device: The index of the device (Default is 0)
:param eventId: The event id. (Default is 2, change it if your device doesnt work)
'''
self.device = client.devices()[device]
self.eventId = eventId
def sendEvent(self, event: str):
"""
Sends a raw adb event.
:param event: The event. Composed by 3 DECIMAL numbers: Type Event Value
"""
self.device.shell(f'sendevent /dev/input/event{self.eventId} {event}')
def startTouch(self):
"""
Starts a touch secuence
(if you want to tap or swipe, use the functions \"tap\", \"swipe\" or \"smoothSwipe\")
"""
self.sendEvent('1 330 1') # BTN_TOUCH Down
self.sendEvent('3 57 10') # PRESSURE
def setPosition(self, position: tuple):
"""
Sends the POSITION_X and POSITION_Y events
(if you want to tap or swipe, use the functions \"tap\" and \"swipe\")
"""
self.sendEvent(f'3 53 {position[0]}') # POSITION_X
self.sendEvent(f'3 54 {position[1]}') # POSITION_Y
# Input functions
def tap(self, position: tuple, duration: float = 0):
"""
Taps the screen in the given location for a specific duration.
:param position: The position to touch.
:param duration: The duration of the tap.
"""
# Start Tap
self.startTouch()
self.setPosition(position)
self.sendEvent('0 0 0') # SYN_REPORT
self.device.shell(f'sleep {duration}')
# End Tap
self.sendEvent('1 330 0') # BTN_TOUCH Up
self.sendEvent('0 0 0') # SYN_REPORT
def swipe(self, positions: list):
"""
Swipes in the screen going to the positions really fast
:param positions: The points to reach
"""
# Start the swipe
self.startTouch()
# Cycle through the positions
for pos in positions:
self.setPosition(pos)
self.sendEvent('0 0 0') # SYN_REPORT
# End swipe
self.sendEvent('1 330 0') # BTN_TOUCH Up
self.sendEvent('0 0 0') # SYN_REPORT
def smoothSwipe(self, positions: list, wait: float = 0, smoothness: int = 10):
'''
Swipes in the screen going to the positions \"smoothly\".
:param positions: The points to reach.
:param wait: The wait between touches (recomend using 0 or something really close)
:param smoothness: The number of extra points added to each path to smooth it (Default = 10)
'''
# Get the needed points
points = []
for p in range(1, len(positions)):
points += lerp(positions[p - 1], positions[p], smoothness)
# Start swipe
self.startTouch()
# Cylce through points waiting the needed
for point in points[:-1]:
self.setPosition(point)
self.sendEvent('0 0 0')
self.device.shell(f'sleep {wait}')
# End swipe
self.sendEvent('1 330 0') # BTN_TOUCH Up
self.sendEvent('0 0 0') # SYN_REPORT
c = Client()
touch = AdbInput(c, 0)
# Touch
touch.tap((1000,600))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
