summarylogtreecommitdiffstats
path: root/android4-screen-control.py
blob: b1b7bb23bbe30043504a3fffbf7e6362ea25fd97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/env python3
import tkinter as tk
from PIL import Image, ImageTk
import subprocess
import threading
import time
import os

# Глобальные
current_image = None
drag_start = None
action_queue = []
stop_event = threading.Event()

# Пути
SCREENSHOT_PATH_PHONE = "/sdcard/adb_screen.png"
SCREENSHOT_PATH_LOCAL = "adb_screen.png"
UPDATE_INTERVAL = 0.5

def run_adb_command(cmd):
    try:
        result = subprocess.run(['adb'] + cmd, capture_output=True, text=True, timeout=5)
        return result.returncode == 0
    except:
        return False

def screenshot_worker():
    while not stop_event.is_set():
        if run_adb_command(['shell', 'screencap', '-p', SCREENSHOT_PATH_PHONE]):
            if run_adb_command(['pull', SCREENSHOT_PATH_PHONE, SCREENSHOT_PATH_LOCAL]):
                if os.path.exists(SCREENSHOT_PATH_LOCAL):
                    update_image()
        time.sleep(UPDATE_INTERVAL)

def send_actions():
    while not stop_event.is_set():
        if action_queue:
            action = action_queue.pop(0)
            if action[0] == 'tap':
                _, x, y = action
                run_adb_command(['shell', 'input', 'tap', str(x), str(y)])
                print(f"✅ tap {x} {y}")
            elif action[0] == 'swipe':
                _, x1, y1, x2, y2 = action
                run_adb_command(['shell', 'input', 'swipe', str(x1), str(y1), str(x2), str(y2), '300'])
                print(f"✅ swipe ({x1},{y1}) → ({x2},{y2})")
        time.sleep(0.1)

def update_image():
    global current_image
    try:
        img = Image.open(SCREENSHOT_PATH_LOCAL)
        max_width, max_height = 800, 1200
        img.thumbnail((max_width, max_height), Image.Resampling.LANCZOS)
        current_image = ImageTk.PhotoImage(img)
        canvas.config(width=img.width, height=img.height)
        canvas.create_image(0, 0, anchor=tk.NW, image=current_image)
    except Exception as e:
        print(f"❌ Ошибка загрузки изображения: {e}")

def on_click(event):
    x, y = event.x, event.y
    orig_w, orig_h = get_original_size()
    scaled_w = canvas.winfo_width()
    scaled_h = canvas.winfo_height()
    if scaled_w == 1 or scaled_h == 1:
        return
    ratio_x = orig_w / scaled_w
    ratio_y = orig_h / scaled_h
    real_x = int(x * ratio_x)
    real_y = int(y * ratio_y)
    action_queue.append(('tap', real_x, real_y))

def on_drag_start(event):
    global drag_start
    drag_start = (event.x, event.y)

def on_drag_end(event):
    global drag_start
    if drag_start is None:
        return
    x1, y1 = drag_start
    x2, y2 = event.x, event.y
    if abs(x2 - x1) < 5 and abs(y2 - y1) < 5:
        drag_start = None
        return  
    orig_w, orig_h = get_original_size()
    scaled_w = canvas.winfo_width()
    scaled_h = canvas.winfo_height()
    if scaled_w == 1 or scaled_h == 1:
        drag_start = None
        return
    ratio_x = orig_w / scaled_w
    ratio_y = orig_h / scaled_h
    real_x1 = int(x1 * ratio_x)
    real_y1 = int(y1 * ratio_y)
    real_x2 = int(x2 * ratio_x)
    real_y2 = int(y2 * ratio_y)
    action_queue.append(('swipe', real_x1, real_y1, real_x2, real_y2))
    drag_start = None

def get_original_size():
    
    try:
        result = subprocess.run(['adb', 'shell', 'wm', 'size'], capture_output=True, text=True)
        if 'Physical size:' in result.stdout:
            line = [l for l in result.stdout.split('\n') if 'Physical size:' in l][0]
            size = line.split(': ')[1].strip()  
            w, h = map(int, size.split('x'))
            return w, h
        else:
            img = Image.open(SCREENSHOT_PATH_LOCAL)
            return img.size
    except:
        return 1080, 1920 

# === GUI ===
screen_size = subprocess.run(['adb', 'shell', 'wm', 'size'], capture_output=True, text=True)
screen_line = [l for l in screen_size.stdout.split('\n') if 'Physical size:' in l][0]
screen = screen_line.split(': ')[1].strip()  
root = tk.Tk()
root.title("A4SC — ЛКМ: клик, ПКМ+перетащи: свайп")
root.geometry(screen)

canvas = tk.Canvas(root, bg="black")
canvas.pack(fill=tk.BOTH, expand=True)

canvas.bind("<Button-1>", on_click)              # Левый клик → tap
canvas.bind("<Button-3>", on_drag_start)         # Правый клик → начало свайпа
canvas.bind("<ButtonRelease-3>", on_drag_end)    # Отпускание → конец свайпа

# === Запуск потоков ===
threading.Thread(target=screenshot_worker, daemon=True).start()
threading.Thread(target=send_actions, daemon=True).start()

print("📱 Подключение к Android через ADB...")
if not subprocess.run(['adb', 'devices'], capture_output=True).returncode == 0:
    print("❌ ADB не найден")
    exit(1)
    
print("🖼️ Ожидание первого скриншота...")
time.sleep(2)

root.mainloop()

# Завершение
stop_event.set()
if os.path.exists(SCREENSHOT_PATH_LOCAL):
    os.remove(SCREENSHOT_PATH_LOCAL)