Hướng dẫn
Python ADB: điều khiển giả lập Android bằng Python
Hướng dẫn Python ADB trong Macro Automation Studio: chạm, vuốt, gõ chữ, nhấn phím và chụp màn hình trên BlueStacks, với adb do ứng dụng quản lý thay bạn.
- Windows
- Mac
- Giả lập
- Thiết bị đám mây
- Điện thoại
- Python SDK
Trong trang này
- Trước khi bắt đầu
- Các mảnh ghép khớp với nhau thế nào
- Tạo dự án
- Kích thước màn hình và tọa độ
- Chụp màn hình bằng Python ADB
- Chạm
- Vuốt
- Gõ chữ
- Nhấn phím
- Mở và kiểm tra ứng dụng
- Một đoạn mã hoàn chỉnh
- adb nằm ở đâu trong hướng dẫn Python ADB này
- Điều gì có thể sai
- Could not discover RPC port
- Cú chạm rơi sai chỗ
- input_text không gõ gì
- Không tìm thấy thiết bị hoặc offline
Hầu hết hướng dẫn Python ADB kết thúc bằng một lớp bọc subprocess quanh adb shell input tap. Hướng dẫn Python ADB này cho Macro Automation Studio (MAS) đi hướng khác: ứng dụng nắm adb, và mã của bạn nói chuyện với ứng dụng qua gói mas. Hướng dẫn đi từ một dự án mới đến đoạn mã mở ứng dụng, tìm một từ khóa, cuộn và lưu ảnh chụp màn hình. Trang dành cho lập trình viên Python muốn điều khiển BlueStacks, LDPlayer, MuMu Player hoặc MEmu mà không phải viết lời gọi adb.
Trước khi bắt đầu
- MAS đã cài và bạn đã đăng nhập với bản dùng thử hoặc gói. Xem Cài đặt MAS.
- Một giả lập đang chạy với ADB đã bật và đã thêm làm thiết bị trong Nhóm thiết bị. Xem Thiết bị.
- Bạn biết Python cơ bản. Bạn không phải cài gì thêm: MAS mang theo môi trường Python 3.13 riêng với
masbên trong.
Các mảnh ghép khớp với nhau thế nào
MAS khởi chạy mã của bạn bằng python -u -m src.app với thư mục dự án làm thư mục làm việc. Nó truyền thông tin kết nối qua biến môi trường (MAS_RPC_PORT, MAS_RPC_HOST, MAS_DEVICE_ID, MAS_SESSION_TOKEN). Mỗi lời gọi mas.* trở thành một yêu cầu JSON-RPC 2.0 tới ứng dụng. Ứng dụng chạy lệnh adb, tìm ảnh mẫu hoặc OCR, và gửi kết quả về. Thiết bị đã được gắn trước khi dòng đầu tiên của bạn chạy, nên không có lời gọi connect() và không có số sê-ri nào phải quản lý. Xem Khái niệm.
Tạo dự án
- Mở Macro và nhấn Tạo dự án mới.
- Chọn Code-Based, đặt Thiết bị đích là mobile, đặt tên dự án và nhấn Tạo dự án.
- Mở dự án. Code Editor hiển thị
src/app.py. - Chọn giả lập trong ô chọn thiết bị và nhấn Chạy (F5) mỗi khi bạn muốn thử một đoạn mã. Dừng là Shift+F5.
Kích thước màn hình và tọa độ
Mọi tọa độ bạn truyền cho SDK là độ lệch pixel tính từ góc trên bên trái màn hình thiết bị, theo độ phân giải riêng của thiết bị. Kích thước cửa sổ giả lập trên màn hình máy tính của bạn không quan trọng.
import mas
size = mas.get_screen_size()
print(f"Screen: {size.width}x{size.height}")
center = (size.width // 2, size.height // 2)
mas.click(*center)get_screen_size() trả về một ScreenSize với width và height. get_device_info() trả về cùng thông tin đó kèm name, type và cờ connected của thiết bị. Khi mã phải sống sót qua thay đổi độ phân giải, hãy tính vị trí theo tỷ lệ của kích thước, như ví dụ ở cuối. Ảnh mẫu và vùng OCR thì không sống sót được; xem hướng dẫn nhận diện hình ảnh.
Chụp màn hình bằng Python ADB
import base64
import mas
shot = mas.take_screenshot()
print(shot.width, shot.height, shot.timestamp)
with open("screen.png", "wb") as f:
f.write(base64.b64decode(shot.base64))take_screenshot() trả về một Screenshot: base64 chứa một ảnh PNG, width và height là kích thước pixel của nó, và timestamp là chuỗi ISO 8601. Tệp ở trên rơi vào thư mục dự án vì đó là thư mục làm việc. Truyền cùng đối tượng đó cho nhiều lời gọi find_object với screenshot=shot và tất cả sẽ tìm trên một khung hình thay vì chụp lại.
Chạm
mas.click(270, 800) # tap, then wait 1000 ms
mas.click(270, 800, delay_ms=300) # shorter pause for tight loopsclick(x, y, delay_ms=1000) chạm một lần và chờ delay_ms sau đó để ứng dụng kịp phản ứng. Không có thời lượng giữ trên cú chạm; để nhấn giữ, dùng key_press với duration_ms.
Vuốt
mas.swipe((270, 750), (270, 300), duration_ms=400) # scroll a list down: drag from lower to upper
mas.swipe((100, 500), (400, 500), duration_ms=1000) # drag and drop: slow and deliberateswipe(from_coords, to_coords, duration_ms=1000) nhận hai bộ (x, y). Thời lượng ngắn là vuốt nhanh; thời lượng dài là kéo. Cử chỉ chụm là các lời gọi riêng: zoom_in() và zoom_out() mặc định ở giữa màn hình với percent=50.
Gõ chữ
mas.click(270, 120, delay_ms=500) # focus the field first
mas.input_text("hello world")
mas.input_text("new value", clear=True) # replace what is thereinput_text(text, delay_ms=0, clear=False) gõ vào ô đang có tiêu điểm, nên hãy chạm vào ô trước. clear=True đưa con trỏ về cuối và xóa các ký tự hiện có trước khi gõ.
Nhấn phím
from mas import KeyCode
mas.key_press(KeyCode.BACK)
mas.key_press(KeyCode.HOME)
mas.key_press(KeyCode.ENTER)
mas.key_press(KeyCode.DELETE, repeat=10) # ten presses in one command
mas.key_press(KeyCode.POWER, duration_ms=3000) # long presskey_press(key_code, modifiers=None, duration_ms=100, repeat=1) gửi một sự kiện phím Android. duration_ms từ 500 trở lên trở thành nhấn giữ; số mili giây chính xác vượt quá mức đó không được tôn trọng. repeat chạy từ 1 đến 100 và nhanh hơn nhiều so với vòng lặp Python. KeyCode cũng có các phím D-pad, âm lượng, media và số.
Mở và kiểm tra ứng dụng
mas.open_app("com.android.settings", timeout_ms=5000)
print(mas.get_current_app()) # package name in front
print(mas.is_app_focused("com.android.settings")) # True or False
if mas.get_app_state("com.android.chrome") == mas.NOT_RUNNING:
mas.open_app("com.android.chrome")
mas.close_app("com.android.settings")open_app(package_name, timeout_ms=2000) khởi chạy theo tên gói và chờ timeout_ms. Để biết tên gói, mở ứng dụng bằng tay và in mas.get_current_app(). get_app_state trả về NOT_INSTALLED, NOT_RUNNING, RUNNING_IN_BACKGROUND_SUSPENDED, RUNNING_IN_BACKGROUND hoặc RUNNING_IN_FOREGROUND. close_app buộc dừng gói.
Một đoạn mã hoàn chỉnh
Mã này mở Cài đặt Android, tìm một từ khóa, cuộn kết quả, lưu ảnh chụp màn hình và kiểm tra bằng OCR rằng từ khóa có trên màn hình. Ô tìm kiếm là một ảnh mẫu bạn cắt trong Asset Lab; thay ID bằng của bạn. Cú vuốt dùng tỷ lệ của kích thước màn hình nên hoạt động ở mọi độ phân giải.
import base64
import sys
import time
import mas
from mas import KeyCode
PACKAGE = "com.android.settings"
TERM = "Display"
images = mas.images({"search_box": 301})
def main():
size = mas.get_screen_size()
mas.log(f"Screen {size.width}x{size.height}")
mas.open_app(PACKAGE, timeout_ms=5000)
if not mas.is_app_focused(PACKAGE):
mas.log(f"{PACKAGE} did not come to the front", level="error")
sys.exit(2)
box = mas.find_object_retry(images.search_box, total_tries=3, time_sleep=2.0)
if box is None:
mas.log("Search box not found; crop it in Asset Lab", level="error")
sys.exit(2)
mas.click(box.x, box.y, delay_ms=800)
mas.input_text(TERM, clear=True)
mas.key_press(KeyCode.ENTER)
time.sleep(2)
x = size.width // 2
mas.swipe((x, int(size.height * 0.75)), (x, int(size.height * 0.35)), duration_ms=600)
time.sleep(1)
shot = mas.take_screenshot()
with open("search_results.png", "wb") as f:
f.write(base64.b64decode(shot.base64))
mas.log(f"Saved search_results.png ({shot.width}x{shot.height})")
text = mas.read_text(screenshot=shot, psm=11)
mas.log(f"Term on screen: {TERM.lower() in text.text.lower()}")
mas.key_press(KeyCode.HOME)
if __name__ == "__main__":
main()read_text với psm=11 đọc chữ rải rác trên toàn khung hình, hợp với một danh sách kết quả. Hướng dẫn OCR nói về vùng và chế độ để đọc một bộ đếm. Nếu bạn muốn mô tả tác vụ thay vì viết, MAS Agent viết loại mã này cho bạn.
adb nằm ở đâu trong hướng dẫn Python ADB này
Bạn không bao giờ gọi adb, nhưng nó đang làm việc bên dưới.
- Tệp nhị phân. Bộ cài mang theo adb. Trên Windows nó nằm tại
C:\ProgramData\MacroAutomationStudio\3rdparty, với bản tích hợp làm dự phòng. Trên Mac nó nằm trong gói ứng dụng, với adb của Homebrew làm dự phòng. Không có gì được thêm vào PATH của bạn. Trang Cài đặt có chi tiết. - Kết nối. Giả lập mở adb trên một cổng TCP cục bộ. Khi bạn nhấn Bắt đầu hoặc Chạy, MAS chạy
adb connect 127.0.0.1:<port>với cổng trên thẻ thiết bị và giữ phiên đó cho lần chạy. - Thao tác.
clicktrở thànhadb shell input tap,swipetrở thànhadb shell input touchscreen swipe,input_texttrở thànhadb shell input text, vàkey_presstrở thànhadb shell input keyevent. Cử chỉ chụm được ghi thẳng vào thiết bị nhập cảm ứng của giả lập. - Màn hình.
take_screenshotvà mọifind_objectchụp bằngadb exec-out screencap -p, dạng an toàn nhị phân không làm hỏng PNG trên Windows.get_screen_sizeđọcwm size;get_current_appđọc trình quản lý cửa sổ. - Ứng dụng.
open_appkích hoạt intent của launcher quamonkeyvà dự phòng bằngam start;close_appchạyam force-stop. - Máy chủ. MAS chạy máy chủ adb riêng. Nếu một bản adb thứ hai trên PATH của bạn khởi động máy chủ riêng, hai bên thay thế lẫn nhau và thiết bị của bạn rơi về Đang kết nối. Trang Khắc phục sự cố ADB liệt kê cách sửa, theo từng cổng.
Vì ứng dụng làm tất cả những việc này, một đoạn mã viết trên BlueStacks chạy không đổi trên LDPlayer, trên thiết bị cloud, hoặc trên điện thoại của bạn qua một cổng cục bộ.
Điều gì có thể sai
Could not discover RPC port
Mã được khởi chạy từ terminal thay vì từ MAS, nên thiếu biến môi trường. Chạy bằng Chạy trong Code Editor hoặc từ thẻ thiết bị.
Cú chạm rơi sai chỗ
Bạn đang dùng pixel của cửa sổ thay vì pixel của thiết bị, hoặc độ phân giải giả lập đã đổi. In mas.get_screen_size() và so với tọa độ bạn truyền. Tọa độ từ Asset Lab đã là pixel của thiết bị.
input_text không gõ gì
Không có ô nào có tiêu điểm. Chạm vào ô bằng click và cho nó delay_ms=500 trước khi gõ. Một số ứng dụng mở bàn phím che mất ô; key_press(KeyCode.BACK) đóng bàn phím sau khi gõ.
Không tìm thấy thiết bị hoặc offline
ADB đang tắt trong giả lập, cổng trên thẻ thiết bị sai, hoặc một máy chủ adb khác đã chiếm quyền. Làm theo Khắc phục sự cố ADB.
Nếu ứng dụng bạn điều khiển là game, hãy đối xử với nó cẩn thận như với mọi tài khoản tự động khác. Không có công cụ tự động hóa nào an toàn 100%, vì vậy hãy tự động hóa một cách có trách nhiệm và theo quyết định của riêng bạn.
Bước tiếp theo
Trang liên quan
Cảm ơn bạn. Nếu có gì chưa đúng, hãy nói với chúng tôi trên Discord.
Có câu hỏi? Hỏi trên Discord