def connect(addr=None):
if not addr or addr == '+':
#在环境变量中获取设备
addr = os.getenv('ANDROID_DEVICE_IP'):
if _is_wifi_addr(addr):
#通过统一wifi网络连接
return connect_wifi(addr)
//通过usb连接
return connect_usb(addr)
  • 我使用的是usb连接,通过设备的serial号进行关联:
def connect_usb(serial=None):
"""
serial (str): android序列号可以通过adb devices获取
返回值:UIAutomatorServer
"""
adb = adbutils.AdbClient()
if not serial:
# 通过遍历设备列表,找到并判断是否存在设备,或者是否存在唯一设备
device = adb.must_one_device()
else:
device = adbutils.AdbDevice(adb, serial)
# adb = adbutils.Adb(serial)
lport = device.forward_port(7912)
d = connect_wifi('127.0.0.1:' + str(lport))
if not d.agent_alive:
# 获取设备服务信息 ,一定要打开ATX 中的启动UiautoMator服务
warnings.warn("backend atx-agent is not alive, start again ...",
RuntimeWarning)

device.shell_output("/data/local/tmp/atx-agent", "server", "-d")
deadline = time.time() + 3
while time.time() < deadline:
if d.alive:
break
elif not d.alive:
warnings.warn("backend uiautomator2 is not alive, start again ...",
RuntimeWarning)
d.reset_uiautomator()
return d
  • details.device_info:
获取的是android system info目录下的信息
  • def app_start(self,
    pkg_name,
    activity=None,
    extras={},
    wait=True,
    stop=False,
    unlock=False):
if activity:
args = [
'am', 'start', '-a', 'android.intent.action.MAIN', '-c',
'android.intent.category.LAUNCHER'
]
  • details.press(‘home’):
def press(self, *keys):
"""
Android系统中关键码定义[\[Android关键码\]](https://developer.android.com/reference/android/view/KeyEvent.html)
key (str): on of
("home", "back", "left", "right", "up", "down", "center",
"search", "enter", "delete", "del", "recent", "volume_up",
"menu", "volume_down", "volume_mute", "camera", "power")
"""
obj.server.jsonrpc.registerPressKeyskWatcher(
name, self.__selectors, keys)
  • details.unlock():
def unlock(self):
# 启动com.github.uiautomator/.IdentifyActivity'
self.open_identify()
# 回到主界面
self._default_session.press("home")
  • 入门级别的小测试:
import uiautomator2 as u2
from PIL import Image
import time
details = u2.connect('serial')
sess = details.session("com.tencent.mobileqq")
sess.running()
# 会存在性能问题,多次登录进入退出,会有加载延迟,所以采用延时函数待画面加载完成后在进行点击
while True:
#定位到输入密码控件
details(resourceId="com.tencent.mobileqq:id/password").clear_text()
details(resourceId="com.tencent.mobileqq:id/password").set_text("13942612530")
details.set_fastinput_ime(False)
details(resourceId="com.tencent.mobileqq:id/login").click()

#点击通知圆点并实现拖拽
details(className="android.widget.TabWidget", resourceId="android:id/tabs")\
.child(className="android.widget.RelativeLayout")\
.child(className="android.widget.TextView", resourceId="com.tencent.mobileqq:id/name").drag_to(259,1299)

#向上滑动10
# details(resourceId="com.tencent.mobileqq:id/recent_chat_list").scroll(steps=10)

#点击头像个人中心,但是此时子线程还没有处理结束画面还没有绘制
time.sleep(3.0)
details(resourceId="com.tencent.mobileqq:id/conversation_head").click()
# details.click(83,155)


#点击设置
time.sleep(3.0)
details(resourceId="com.tencent.mobileqq:id/name", className="android.widget.ImageView", instance=21).click()


time.sleep(3.0)
#点击账号管理
details(resourceId="com.tencent.mobileqq:id/account_switch").click()


time.sleep(3.0)
#点击退出登录
details(resourceId="com.tencent.mobileqq:id/logoutBtn").click()


time.sleep(2.0)
#点击确认退出
details(resourceId="com.tencent.mobileqq:id/dialogRightBtn").click()

#清空密码栏
details(resourceId="com.tencent.mobileqq:id/password").clear_text()