Android Uiautomator2 Python Wrapper设备控制API:屏幕旋转、亮度与音量调节
Android Uiautomator2 Python Wrapper设备控制API:屏幕旋转、亮度与音量调节
一、设备控制API概述
Android Uiautomator2 Python Wrapper(以下简称uiautomator2)是一款功能强大的Android设备自动化测试框架,提供了丰富的设备控制API。本文将聚焦于三个核心设备控制功能:屏幕旋转管理、亮度调节和音量控制,通过实际代码示例和场景化应用,帮助开发者快速掌握这些API的使用方法。
1.1 核心控制维度
uiautomator2将设备控制功能划分为三个主要维度:
| 控制维度 | 核心API | 应用场景 |
|---|---|---|
| 屏幕旋转 | orientation属性、freeze_rotation() | 视频播放测试、横竖屏切换场景 |
| 亮度调节 | shell命令封装 | 功耗测试、夜间模式模拟 |
| 音量控制 | press()、keyevent() | 媒体播放测试、通知音量验证 |
1.2 API调用流程
设备控制API的典型调用流程如下:
初始化示例:
import uiautomator2 as u2
# 连接设备
d = u2.connect("127.0.0.1:62001") # 替换为实际设备序列号或IP
print(f"设备信息: {d.device_info}")
二、屏幕旋转控制
屏幕旋转是移动应用测试中的常见需求,特别是在游戏、视频类应用中。uiautomator2提供了完整的屏幕旋转管理方案。
2.1 支持的旋转模式
uiautomator2定义了四种标准屏幕旋转模式:
# 设备旋转模式定义(源码解析)
__orientation = (
(0, "natural", "n", 0), # 自然方向
(1, "left", "l", 90), # 向左旋转(横屏)
(2, "upsidedown", "u", 180), # 上下颠倒(需API 18+)
(3, "right", "r", 270) # 向右旋转(横屏)
)
2.2 旋转控制API详解
2.2.1 获取当前旋转状态
# 获取当前旋转状态
current_orient = d.orientation
print(f"当前旋转状态: {current_orient}") # 输出: natural/left/right/upsidedown
# 获取详细显示信息
display_info = d.info.get("displayRotation")
print(f"显示旋转角度: {display_info}") # 输出: 0/1/2/3 (对应0°/90°/180°/270°)
2.2.2 设置旋转方向
# 设置为自然方向
d.orientation = "natural" # 或使用简写 "n"
# 设置为向左旋转(横屏)
d.orientation = "left" # 或使用简写 "l"
# 设置为向右旋转(横屏)
d.orientation = "right" # 或使用简写 "r"
# 设置为上下颠倒(需Android 4.3+)
d.orientation = "upsidedown" # 或使用简写 "u"
2.2.3 锁定/解锁旋转
# 锁定当前旋转状态
d.freeze_rotation(True)
# 解锁旋转(允许自动旋转)
d.freeze_rotation(False)
2.3 实战应用:视频播放场景测试
场景需求:模拟用户在视频播放过程中切换横竖屏的操作。
def test_video_orientation():
# 启动视频应用
d.app_start("com.netease.cloudmusic")
# 等待应用启动
d.wait_activity("com.netease.cloudmusic.activity.MainActivity", timeout=10)
# 模拟点击播放按钮(假设坐标)
d.click(500, 1500)
# 等待视频开始播放
d.sleep(3)
# 切换至横屏模式
d.orientation = "right"
assert d.orientation == "right", "横屏切换失败"
# 播放5秒
d.sleep(5)
# 切换回竖屏模式
d.orientation = "natural"
assert d.orientation == "natural", "竖屏切换失败"
# 退出应用
d.app_stop("com.netease.cloudmusic")
三、亮度调节方案
uiautomator2本身未提供直接的亮度调节API,但可以通过Android系统的Settings数据库和adb shell命令实现亮度控制。
3.1 亮度调节原理
Android系统亮度设置存储在Settings.System数据库中,主要涉及两个关键参数:
screen_brightness:亮度值(0-255)screen_brightness_mode:亮度模式(0=手动,1=自动)
3.2 亮度控制实现
3.2.1 获取当前亮度
def get_brightness(d):
"""获取当前屏幕亮度"""
result = d.shell("settings get system screen_brightness")
return int(result.output.strip())
def get_brightness_mode(d):
"""获取亮度模式(0=手动,1=自动)"""
result = d.shell("settings get system screen_brightness_mode")
return int(result.output.strip())
# 使用示例
current_brightness = get_brightness(d)
current_mode = get_brightness_mode(d)
print(f"当前亮度: {current_brightness}, 模式: {'自动' if current_mode else '手动'}")
3.2.2 设置亮度
def set_brightness(d, level):
"""
设置屏幕亮度
:param level: 亮度值(0-255)
"""
# 先切换到手动模式
d.shell("settings put system screen_brightness_mode 0")
# 设置亮度值
d.shell(f"settings put system screen_brightness {level}")
return get_brightness(d)
# 使用示例
set_brightness(d, 128) # 设置中等亮度
assert get_brightness(d) == 128, "亮度设置失败"
set_brightness(d, 255) # 设置最大亮度
3.3 亮度测试场景
场景需求:测试应用在不同亮度下的UI显示效果。
def test_ui_brightness():
# 保存原始亮度设置
original_brightness = get_brightness(d)
original_mode = get_brightness_mode(d)
try:
# 测试低亮度场景
set_brightness(d, 50)
d.sleep(2)
d.screenshot("low_brightness_ui.png")
# 测试中等亮度场景
set_brightness(d, 150)
d.sleep(2)
d.screenshot("medium_brightness_ui.png")
# 测试高亮度场景
set_brightness(d, 255)
d.sleep(2)
d.screenshot("high_brightness_ui.png")
finally:
# 恢复原始设置
d.shell(f"settings put system screen_brightness {original_brightness}")
d.shell(f"settings put system screen_brightness_mode {original_mode}")
四、音量控制API
uiautomator2提供了便捷的音量控制API,支持通过按键事件和直接命令两种方式调节音量。
4.1 音量控制API
4.1.1 按键式调节
# 增加音量
d.press("volume_up")
# 降低音量
d.press("volume_down")
# 静音
d.press("volume_mute")
# 长按音量键(连续调节)
d.long_press("volume_up") # 长按音量+
4.1.2 直接发送按键事件
# 使用keyevent发送音量键事件
d.keyevent("volume_up")
d.keyevent("volume_down")
d.keyevent("volume_mute")
4.1.3 支持的音量控制键
uiautomator2定义的音量相关按键常量:
# 源码位置:uiautomator2/watcher.py
SUPPORTED_KEYS = [
"volume_up", "volume_down", "volume_mute"
]
4.2 音量测试场景
场景需求:测试媒体播放器的音量调节功能。
def test_media_volume():
# 启动媒体应用
d.app_start("com.netease.cloudmusic")
# 播放音乐(假设已登录并缓存歌曲)
d.click(300, 1000) # 点击播放按钮
d.sleep(2)
# 最大音量设置
for _ in range(15): # 连续按15次音量+
d.press("volume_up")
d.sleep(0.2)
# 验证最大音量(需系统支持获取当前音量)
max_vol = get_media_volume(d)
assert max_vol == 15, f"预期最大音量15,实际{max_vol}"
# 降低音量
for _ in range(5):
d.press("volume_down")
d.sleep(0.2)
# 静音
d.press("volume_mute")
d.sleep(2)
# 取消静音
d.press("volume_up")
# 停止播放
d.click(300, 1000) # 点击暂停按钮
# 退出应用
d.app_stop("com.netease.cloudmusic")
def get_media_volume(d):
"""获取媒体音量(需要root权限或系统应用)"""
result = d.shell("media volume --get media")
# 解析输出,例如:"Current volume for media: 15 (max:15)"
import re
match = re.search(r"Current volume for media: (\d+)", result.output)
return int(match.group(1)) if match else 0
五、综合应用:设备状态管理工具类
基于以上API,我们可以封装一个设备状态管理工具类,方便在测试框架中复用。
class DeviceManager:
def __init__(self, device):
self.d = device
self.original_orientation = None
self.original_brightness = None
self.original_brightness_mode = None
def save_state(self):
"""保存当前设备状态"""
self.original_orientation = self.d.orientation
self.original_brightness = get_brightness(self.d)
self.original_brightness_mode = get_brightness_mode(self.d)
def restore_state(self):
"""恢复设备状态"""
# 恢复旋转状态
self.d.orientation = self.original_orientation
# 恢复亮度设置
set_brightness(self.d, self.original_brightness)
self.d.shell(f"settings put system screen_brightness_mode {self.original_brightness_mode}")
# 恢复音量(设为中等)
for _ in range(10):
self.d.press("volume_down")
for _ in range(5):
self.d.press("volume_up")
def set_full_brightness(self):
"""设置最大亮度(测试专用)"""
set_brightness(self.d, 255)
def set_natural_orientation(self):
"""设置为自然方向"""
self.d.orientation = "natural"
self.d.freeze_rotation(False)
# 使用示例
dm = DeviceManager(d)
try:
dm.save_state()
# 执行测试操作
dm.set_full_brightness()
dm.set_natural_orientation()
# ...测试步骤...
finally:
dm.restore_state() # 确保测试后恢复设备状态
六、常见问题与解决方案
6.1 屏幕旋转失败
问题表现:设置orientation后无反应或抛出异常。
解决方案:
- 检查应用是否禁用了屏幕旋转
# 检查应用旋转设置 rotation_lock = d.shell("settings get secure user_rotation") print(f"用户旋转锁状态: {rotation_lock.output}") - 确保设备未处于充电状态(部分设备充电时禁用旋转)
- 对于"upsidedown"模式,需确认设备API版本≥18
6.2 亮度调节不生效
问题表现:设置亮度后屏幕无变化。
解决方案:
- 确认应用具有修改系统设置权限
# 授予权限(需root或系统签名) d.shell("pm grant com.github.uiautomator android.permission.WRITE_SETTINGS") - 检查是否处于自动亮度模式
# 强制关闭自动亮度 d.shell("settings put system screen_brightness_mode 0")
6.3 音量调节无反应
问题表现:调用press("volume_up")后音量无变化。
解决方案:
- 检查当前音量是否已达极限值
- 确认设备是否处于静音模式
# 检查静音状态 result = d.shell("getprop ro.config.ringtone") - 尝试使用keyevent方式
d.keyevent(24) # 音量+键码 d.keyevent(25) # 音量-键码
七、总结与最佳实践
7.1 核心API总结
| 功能 | 实现方式 | 关键代码 |
|---|---|---|
| 旋转控制 | orientation属性 | d.orientation = "right" |
| 旋转锁定 | freeze_rotation() | d.freeze_rotation(True) |
| 亮度调节 | shell命令 | d.shell("settings put system screen_brightness 255") |
| 音量控制 | press()方法 | d.press("volume_up") |
7.2 最佳实践建议
- 状态管理:测试前保存设备状态,测试后恢复,避免影响后续测试
- 异常处理:对设备控制操作添加超时和重试机制
- 权限检查:在执行系统设置修改前验证必要权限
- 兼容性考虑:针对不同API版本和设备型号设计适配代码
7.3 扩展学习资源
- uiautomator2官方文档:项目中的
README.md和QUICK_REFERENCE.md - Android开发者文档:屏幕旋转
- 设备控制进阶:探索
uiautomator2.ext扩展模块
通过本文介绍的API和实践方法,开发者可以轻松实现对Android设备的屏幕旋转、亮度和音量的精确控制,为自动化测试和设备管理提供有力支持。建议结合实际项目需求,进一步扩展和封装这些基础API,构建更强大的设备控制工具集。
更多推荐


所有评论(0)