Files
workphone-sdk/sdk/app/skills/base.py

125 lines
3.4 KiB
Python

"""
工作手机SDK v3.0 - 技能基类
所有APP脚本的父类
"""
from abc import ABC, abstractmethod
from typing import Dict, Any, Optional
import logging
logger = logging.getLogger(__name__)
class BaseSkill(ABC):
"""技能基类"""
# 子类必须定义
PACKAGE: str = "" # APP包名
NAME: str = "" # APP中文名
def __init__(self, device):
"""
初始化技能
Args:
device: uiautomator2设备对象
"""
self.d = device
self.d.implicitly_wait(10.0)
# ========== 抽象方法 ==========
@abstractmethod
async def send_message(self, to_id: str, content: str, msg_type: str = "text") -> Dict[str, Any]:
"""发送消息"""
pass
@abstractmethod
async def get_messages(self, limit: int = 20) -> Dict[str, Any]:
"""获取消息列表"""
pass
# ========== 通用方法 ==========
def launch(self) -> bool:
"""启动APP"""
try:
self.d.app_start(self.PACKAGE)
self.d.sleep(2)
return True
except Exception as e:
logger.error(f"启动{self.NAME}失败: {e}")
return False
def close(self):
"""关闭APP"""
self.d.app_stop(self.PACKAGE)
def is_running(self) -> bool:
"""检查APP是否运行"""
return self.d.app_current()['package'] == self.PACKAGE
# ========== UI操作 ==========
def click(self, x: int, y: int):
"""点击坐标"""
self.d.click(x, y)
def click_text(self, text: str, timeout: float = 10) -> bool:
"""点击文字"""
try:
element = self.d(text=text)
if element.wait(timeout=timeout):
element.click()
return True
return False
except Exception as e:
logger.error(f"点击文字失败: {e}")
return False
def click_resource_id(self, resource_id: str) -> bool:
"""点击资源ID"""
try:
self.d(resourceId=resource_id).click()
return True
except Exception:
return False
def input_text(self, text: str, clear: bool = True):
"""输入文字"""
if clear:
self.d.clear_text()
self.d.send_keys(text)
def swipe(self, direction: str, scale: float = 0.8):
"""滑动"""
self.d.swipe_ext(direction, scale=scale)
def exists(self, text: str = None, resource_id: str = None) -> bool:
"""检查元素是否存在"""
if text:
return self.d(text=text).exists(timeout=3)
if resource_id:
return self.d(resourceId=resource_id).exists(timeout=3)
return False
def wait_for(self, text: str = None, resource_id: str = None, timeout: float = 10) -> bool:
"""等待元素出现"""
if text:
return self.d(text=text).wait(timeout=timeout)
if resource_id:
return self.d(resourceId=resource_id).wait(timeout=timeout)
return False
def screenshot(self) -> bytes:
"""截图"""
return self.d.screenshot(format='raw')
def get_ui_tree(self) -> str:
"""获取UI树"""
return self.d.dump_hierarchy()
def sleep(self, seconds: float):
"""等待"""
self.d.sleep(seconds)