""" Android Input Event Implementations Concrete implementations of input events for Android devices. """ from typing import Optional, Dict, Any, List from ...core.abstract_input_event import ( AbstractInputEvent, EventType, BaseTouchEvent, BaseLongTouchEvent, BaseSwipeEvent, BaseScrollEvent, BaseSetTextEvent, BaseKeyEvent, BaseKillAppEvent ) class AndroidTouchEvent(BaseTouchEvent): """Android 触摸事件""" def send(self, device) -> bool: """发送触摸事件到 Android 设备""" x, y = self.x, self.y if self.view is not None: from .android_device_state import AndroidDeviceState x, y = AndroidDeviceState.get_view_center(self.view) device.view_touch(int(x), int(y)) return True class AndroidLongTouchEvent(BaseLongTouchEvent): """Android 长按事件""" def send(self, device) -> bool: """发送长按事件到 Android 设备""" x, y = self.x, self.y if self.view is not None: from .android_device_state import AndroidDeviceState x, y = AndroidDeviceState.get_view_center(self.view) device.view_long_touch(int(x), int(y), self.duration) return True class AndroidSwipeEvent(BaseSwipeEvent): """Android 滑动事件""" def send(self, device) -> bool: """发送滑动事件到 Android 设备""" device.view_drag( (self.start_x, self.start_y), (self.end_x, self.end_y), self.duration ) return True class AndroidScrollEvent(BaseScrollEvent): """Android 滚动事件""" def send(self, device) -> bool: """发送滚动事件到 Android 设备""" display_info = device.get_display_info() width = display_info.get('width', 1080) height = display_info.get('height', 1920) # 计算滚动的起点和终点 center_x = width // 2 center_y = height // 2 if self.direction == self.DIRECTION_UP: start_y = center_y + height // 4 end_y = center_y - height // 4 device.view_drag((center_x, start_y), (center_x, end_y), 300) elif self.direction == self.DIRECTION_DOWN: start_y = center_y - height // 4 end_y = center_y + height // 4 device.view_drag((center_x, start_y), (center_x, end_y), 300) elif self.direction == self.DIRECTION_LEFT: start_x = center_x + width // 4 end_x = center_x - width // 4 device.view_drag((start_x, center_y), (end_x, center_y), 300) elif self.direction == self.DIRECTION_RIGHT: start_x = center_x - width // 4 end_x = center_x + width // 4 device.view_drag((start_x, center_y), (end_x, center_y), 300) return True class AndroidSetTextEvent(BaseSetTextEvent): """Android 文本输入事件""" def send(self, device) -> bool: """发送文本输入事件到 Android 设备""" # 先点击目标视图 if self.view is not None: from .android_device_state import AndroidDeviceState x, y = AndroidDeviceState.get_view_center(self.view) device.view_touch(int(x), int(y)) import time time.sleep(0.5) # 输入文本 device.view_set_text(self.text) # 默认按回车键确认 device.key_press("66") # ENTER key code return True class AndroidKeyEvent(BaseKeyEvent): """Android 按键事件""" # Android 特定按键映射 KEY_MAP = { 'BACK': 'BACK', 'HOME': 'HOME', 'MENU': 'MENU', 'ENTER': '66', 'ESCAPE': '111', 'POWER': 'POWER', 'VOLUME_UP': 'VOLUME_UP', 'VOLUME_DOWN': 'VOLUME_DOWN', } def send(self, device) -> bool: """发送按键事件到 Android 设备""" key_code = self.KEY_MAP.get(self.key_name, self.key_name) device.key_press(key_code) return True class AndroidIntentEvent(AbstractInputEvent): """Android Intent 事件""" def __init__(self, intent=None): """ 初始化 Intent 事件 :param intent: Intent 对象或命令字符串 """ super().__init__(EventType.INTENT) self.intent = intent def send(self, device) -> bool: """发送 Intent 到 Android 设备""" if self.intent is not None: device.send_intent(self.intent) return True def to_dict(self) -> Dict[str, Any]: return { "event_type": self.event_type.value, "intent": str(self.intent) if self.intent else None } def get_event_str(self, _state=None) -> str: return f"Intent({self.intent})" class AndroidKillAppEvent(BaseKillAppEvent): """Android 终止应用事件""" def send(self, device) -> bool: """终止 Android 应用""" if self.app is None: return False package_name = (self.app.get_package_name() if hasattr(self.app, 'get_package_name') else self.app) device.adb.shell(f"am force-stop {package_name}") return True