import subprocess
import re
import time
import uiautomator2 as u2 # 需安装:pip install uiautomator2
from typing import Tuple, Optional
class AndroidDebugger:
def __init__(self):
self.connected_device: Optional[str] = None
self.d = None # uiautomator2 实例
# 核心配置
self.swipe = (500, 1500, 500, 500, 500) # x1,y1,x2,y2,时长
self.clock_id = "com.android.systemui:id/clock"
def _adb(self, cmd: str) -> Tuple[str, str, int]:
"""简化ADB命令执行"""
try:
res = subprocess.run(
f"adb {cmd}",
shell=True,
capture_output=True,
text=True,
timeout=8
)
return res.stdout.strip(), res.stderr.strip(), res.returncode
except Exception as e:
return "", str(e), 1
def check_device(self) -> bool:
"""检测并连接设备"""
out, _, _ = self._adb("devices")
devices = [l.split('\t')[0] for l in out.split('\n')[1:] if l.strip() and 'device' in l]
if not devices:
print("未检测到设备")
return False
self.connected_device = devices[0]
print(f"已连接设备: {self.connected_device}")
# 初始化 uiautomator2
self.d = u2.connect(self.connected_device)
return True
def setup_wireless(self) -> bool:
"""简化无线连接"""
if ':' in self.connected_device:
print("已无线连接")
return True
# 自动获取IP
ip = None
for cmd in ["shell ifconfig wlan0", "shell ip addr show wlan0"]:
out, _, _ = self._adb(cmd)
if match := re.search(r'inet\s*(?:addr:)?\s*(\d+\.\d+\.\d+\.\d+)', out):
ip = match.group(1)
if not ip.startswith("127."):
break
if not ip:
ip = input("输入设备IP: ").strip()
if not re.match(r'^\d+\.\d+\.\d+\.\d+$', ip):
print("IP无效")
return False
# 启动无线调试
self._adb("kill-server && start-server && tcpip 5555")
out, _, code = self._adb(f"connect {ip}:5555")
if code == 0 and 'connected' in out:
self.connected_device = f"{ip}:5555"
self.d = u2.connect(self.connected_device) # 重新连接无线设备
print(f"无线连接成功: {self.connected_device}")
return True
print("无线连接失败")
return False
def unlock(self) -> Tuple[bool, str]:
"""解锁核心逻辑:用 dump_hierarchy() 检测时钟元素"""
if not self.d:
return False, "设备未连接"
# 唤醒+滑动
self._adb("shell input keyevent 26")
x1, y1, x2, y2, dur = self.swipe
self._adb(f"shell input swipe {x1} {y1} {x2} {y2} {dur}")
# 关键修改:用 uiautomator2 的 dump_hierarchy() 获取XML
xml = self.dump_hierarchy()
if self.clock_id in xml:
return True, "解锁成功(检测到时钟元素)"
else:
return False, "解锁失败(未检测到时钟元素)"
def dump_hierarchy(self) -> str:
"""封装 dump_hierarchy 方法"""
try:
return self.d.dump_hierarchy()
except Exception as e:
print(f"获取XML失败: {e}")
return ""
def main():
print("===== 安卓调试工具 =====")
debugger = AndroidDebugger()
if not debugger.check_device():
return
if ':' not in debugger.connected_device:
debugger.setup_wireless()
success, msg = debugger.unlock()
print(f"解锁结果: {'成功' if success else '失败'} - {msg}")
print("===== 操作结束 =====")
if __name__ == "__main__":
main()
已连接到 pydev 调试器(内部版本号 242.26775.22)===== 安卓调试工具 =====
已连接设备: 192.168.101.28:5555
解锁结果: 成功 - 解锁成功(检测到时钟元素)
===== 操作结束 =====