[Python] How to use Python and ADB to control Android devices for mouse operations

How to use Python and ADB to control mouse operations on Android devices

Project Description

This code implements a gadget that can control an Android device using the mouse. It uses the Pygame library to display the device screen and capture mouse events, as well as ADB commands to simulate screen sliding and mouse click events. Specifically, the code implements the following functions:
1. Get the device screen size and set the Pygame window size to match the device resolution.
2. Use ADB commands to capture the device screen and display it in the Pygame window.
3. Handle mouse click events and convert them into ADB commands to perform corresponding operations on the device.
4. Handle mouse movement events and convert them into sliding events on the device screen.
5. Convert sliding events into ADB commands to perform corresponding operations on the device.

Project code

import re
import sys
import pygame
import subprocess
from io import BytesIO

"""
这段代码实现了一个可以使用鼠标控制安卓设备的小工具。它使用了Pygame库来显示设备屏幕和捕获鼠标事件,以及使用了ADB命令来模拟屏幕滑动和鼠标点击事件。具体来说,代码实现了以下功能:
获取设备屏幕大小并设置Pygame窗口大小以匹配设备分辨率。
使用ADB命令捕获设备屏幕并将其显示在Pygame窗口中。
处理鼠标点击事件并将其转换为ADB命令以在设备上执行相应的操作。
处理鼠标移动事件并将其转换为设备屏幕上的滑动事件。
将滑动事件转换为ADB命令以在设备上执行相应的操作。
"""

# 设置ADB命令来捕获设备屏幕和发送鼠标事件
adb_tap_cmd = "adb shell input tap {} {}"

# 设置ADB命令来捕获设备屏幕
adb_cmd = "adb shell screencap -p"

# 初始化Pygame
pygame.init()


def get_screen_size():
    # 使用ADB命令获取安卓设备屏幕大小
    output = subprocess.check_output(['adb', 'shell', 'wm', 'size']).decode()
    match = re.search(r'(\d+)x(\d+)', output)
    if match:
        width, height = int(match.group(1)), int(match.group(2))
        return width, height
    else:
        raise RuntimeError('Failed to get screen size')


# 获取安卓设备屏幕大小
width, height = get_screen_size()

# 设置窗口大小以匹配您的设备分辨率
window_size = (width * 0.3, height * 0.3)
screen = pygame.display.set_mode(window_size)


def save_png_load(screenshot):
    # 将截图保存到本地
    with open('screenshot.png', 'wb') as f:
        f.write(screenshot)
    # 加载截图到Pygame中
    try:
        image = pygame.image.load('screenshot.png')
    except pygame.error as e:
        print(e)
        return ""
    # 缩放图像以适应窗口大小
    image = pygame.transform.scale(image, window_size)
    return image


def swipe(x1, y1, x2, y2, duration=300):
    # 使用ADB命令模拟滑动屏幕事件
    subprocess.run(
        ['adb', 'shell', 'input', 'swipe', str(x1), str(y1), str(x2), str(y2), str(duration)])


# 捕获和显示屏幕
while True:
    # 捕获设备屏幕
    process = subprocess.Popen(adb_cmd.split(), stdout=subprocess.PIPE)
    screenshot = process.communicate()[0].replace(b'\r\n', b'\n')

    # 将截图数据转换为Pillow Image对象
    image = pygame.image.load(BytesIO(screenshot))
    # 缩放图像以适应窗口大小
    image = pygame.transform.scale(image, window_size)

    # 显示图像
    screen.blit(image, (0, 0))
    pygame.display.update()

    # 处理Pygame事件(如关闭窗口或鼠标点击)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # 将鼠标点击事件转换为安卓设备的tap命令
            x, y = event.pos
            x *= width / window_size[0]
            y *= height / window_size[1]
            tap_cmd = adb_tap_cmd.format(int(x), int(y))
            # 发送tap命令到设备
            subprocess.run(tap_cmd.split())
        elif event.type == pygame.MOUSEMOTION:
            # 将鼠标移动事件转换为安卓设备的坐标系
            x, y = event.pos
            x *= width / window_size[0]
            y *= height / window_size[1]
            # 如果鼠标左键已按下,则将鼠标移动事件转换为滑动事件
            if event.buttons[0]:
                # 根据鼠标移动距离计算滑动距离和方向
                dx = event.rel[0]
                dy = event.rel[1]
                distance = (dx ** 2 + dy ** 2) ** 0.5
                direction = (dx / distance, dy / distance)
                # 计算滑动距离和速度
                swipe_distance = min(width, height) * distance / 200
                swipe_duration = int(swipe_distance)

                # 计算滑动的起点和终点
                start_x, start_y = x - direction[0] * swipe_distance / 2, y - direction[1] * swipe_distance / 2
                end_x, end_y = x + direction[0] * swipe_distance / 2, y + direction[1] * swipe_distance / 2

                # 使用ADB命令模拟滑动事件
                swipe_cmd = "adb shell input swipe {} {} {} {} {}".format(
                    int(start_x), int(start_y), int(end_x),
                    int(end_y), swipe_duration
                )
                subprocess.run(swipe_cmd.split())
    # 检查Pygame事件(如关闭窗口)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

Guess you like

Origin blog.csdn.net/linjiuxiansheng/article/details/130528691