ADB+OCRを使ったAndroid画面自動操作スクリプトの作り方
はじめに
Android端末の画面操作を自動化するスクリプトの作成方法を解説します。ADBコマンドとOCR技術を組み合わせ、画面に表示された特定のテキストを自動でタップする仕組みを実装します。
必要な環境
- Python 3.8以上
- ADB(Android Debug Bridge)がセットアップ済み
- Tesseract OCR(日本語対応版)
- 主要ライブラリ:
pip install opencv-python pytesseract numpy
実装手順
1. スクリーンショット取得機能
def get_screenshot():
""" Androidのスクリーンショットを取得し、Windowsのデスクトップへ保存 """
dir_path = os.getcwd()
local_path = os.path.join(dir_path, "screenshot.png")
screenshot_path = "/sdcard/screen.png"
# スクリーンショットを取得
subprocess.run(["adb", "shell", "screencap", "-p", screenshot_path])
# デスクトップへコピー
subprocess.run(["adb", "pull", screenshot_path, local_path])
# Android内部のスクリーンショットを削除
subprocess.run(["adb", "shell", "rm", screenshot_path])
print(f"スクリーンショットを {local_path} に保存しました")
return local_path
ポイント:
-
screencap
で端末内に一時保存→pull
でPCへ転送 - 処理完了後は端末内のファイルを削除
2. 画像前処理
def preprocess_image(image_path):
""" 画像の前処理(グレースケール+ノイズ除去+二値化) """
image = cv2.imread(image_path)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# ノイズ除去
gray = cv2.GaussianBlur(gray, (3, 3), 0)
# 二値化(OCRの精度向上)
_, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return binary
処理フロー:
- グレースケール変換
- ガウシアンブラーでノイズ除去
- 大津の手法を使った自動二値化
3. OCRによるテキスト検索
def find_text_coordinates(image_path, search_texts):
""" OCRで画像から指定の文字列を検索し、最初に見つかった文字の座標をタップ """
processed_image = preprocess_image(image_path)
# OCRで単語ごとに解析(PSM 6 + OEM 3 を指定)
custom_config = r"--psm 6 --oem 3 -l jpn"
d = pytesseract.image_to_data(processed_image, config=custom_config, output_type=pytesseract.Output.DICT)
recognized_texts = [] # すべての認識文字を格納
found_coordinates = None # 見つかった座標
#print("\n--- OCRで認識したすべての文字 ---")
#for i, text in enumerate(d["text"]):
# text = text.strip()
# if text: # 空白でない場合のみ処理
# recognized_texts.append(text)
# print(f"Text {i}: {text} (座標: x={d['left'][i]}, y={d['top'][i]})")
# 優先順位の高い文字から順に検索
for search_text in search_texts:
print(f"\n🔍 検索中: {search_text}")
for i, text in enumerate(d["text"]):
if search_text in text: # 指定の文字列を含む場合
x, y, w, h = d["left"][i], d["top"][i], d["width"][i], d["height"][i]
center_x = x + w // 2
center_y = y + h // 2
found_coordinates = (center_x, center_y)
if search_text == "0/65": #title部分補正
center_y -= 90
# center_y が 70 以下ならスキップして次の候補を探す
if center_y <= 70:
print(f"⚠️ {search_text} の座標 (x={center_x}, y={center_y}) は低すぎるためスキップ")
continue
# ADBのtapコマンドを実行
print(f"✅ {search_text} の座標: (x={center_x}, y={center_y}) をタップします")
run_adb(f"shell input tap {center_x} {center_y}")
return found_coordinates, recognized_texts # 最初に見つかったものを返す
print("❌ 指定したどの文字も見つかりませんでした")
return None, recognized_texts # どれも見つからなかった場合
特徴:
- 複数検索テキストを優先順位付きで指定可能
- 誤検知防止のための座標補正
- 画面上部(y <= 70)の要素を除外
応用例
- モバイルゲームの自動リセマラ
- 定期的な画面チェックの自動化
- アプリテストの自動操作
注意点
- 解像度依存問題:端末ごとの解像度差異に対処するため、座標を比率で計算する改良が可能
- ADB接続:事前に
adb devices
で接続確認が必要 - OCR精度:フォントや背景色によっては認識率が低下する場合あり
まとめ
ADBとOCRを組み合わせることで、以下のメリットが得られます:
- 画面の変化に柔軟に対応
- 座標指定方式より汎用的
- Pythonで簡単にカスタマイズ可能