实现 Android 设备搜索 #21

Closed
opened 2026-08-07 11:41:51 +08:00 by ila · 3 comments
Owner

基本信息

  • 类型:需求
  • 父级大工单:#1
  • 所属 MVP / 版本:#2 / MVP
  • 阶段:3. Admin Mock/Gateway 闭环
  • 依赖:#5、#11
  • 当前状态:验收通过

要解决什么

设置页已经有 Android 设备“搜索”按钮和设备表格,但按钮目前只发出 searchRequested 信号,没有实际执行 ADB 搜索,也没有把结果写回表格。

本任务让用户点击“搜索”后,能够在不阻塞 Qt 主线程的情况下列出当前 ADB 已识别的 USB 和 Wi-Fi Android 设备。

做什么 / 不做什么

  • 做:
    • 新增简单的 ADB 设备查询服务,执行 adb devices -l;
    • 解析设备号、连接方式、型号和 ADB 状态;
    • 对已连接设备查询 Android 版本,单台查询失败时仍保留该设备;
    • 使用 QObject + moveToThread 在后台执行搜索;
    • 搜索期间禁用设备管理命令,防止重复搜索;
    • 搜索成功、无设备、ADB 不可用和命令超时均显示明确的内联状态;
    • 搜索完成后通过现有 set_android_devices() 更新表格;
    • 页面关闭时断开回调并忽略迟到结果;
    • 使用标准库 unittest 覆盖解析、错误和离屏 Qt 线程行为。
  • 不做:
    • 不自动安装、下载或升级 ADB;
    • 不修改系统 PATH;
    • 不执行 adb connect、保存或删除设备;
    • 不创建或共享 uiautomator2 Device 对象;
    • 不修改数据库、Admin 接口和 PDD 自动化流程;
    • 不增加第三方依赖。

怎么做

  1. 新增 client/src/android_device_service.py,通过可注入的命令执行器调用 ADB,方便单元测试。
  2. 解析 adb devices -l 输出;带 : 的序列号显示为 Wi-Fi,其余显示为 USB。
  3. 仅对状态为 device 的设备执行 adb -s <serial> shell getprop ro.build.version.release。
  4. 在 settings_ui_event.py 增加搜索 Worker 和独立线程;Worker 只处理普通数据,不访问 QWidget。
  5. 搜索结果由主线程转换为现有 AndroidDeviceRow 并更新模型;以设备序列号保持仍有效的勾选状态。
  6. 复用设置页底部状态文字显示“正在搜索”“找到 N 台”“未找到”“搜索失败”等状态,不弹模态框。
  7. ADB 命令设置有限超时,按钮快速重复点击只启动一次搜索。
  8. 本次是现有局部交互补全,不调整页面布局,因此不制作 HTML 原型。

预计修改:

  • client/src/android_device_service.py
  • client/src/settings_ui_event.py
  • client/src/settings_ui.py(仅补充必要的无障碍名称或状态接口)
  • client/test/test_android_device_service.py
  • client/test/test_settings_ui_event.py

验收标准

  • 点击“搜索”会在后台执行 ADB 查询,Qt 主线程保持响应;
  • USB 和 Wi-Fi 设备能正确区分并显示;
  • 已连接设备显示型号、Android 版本和“已连接”状态;
  • offline、unauthorized 等设备仍显示,并且不可勾选保存;
  • 没有设备时表格保留空白占位行,并提示“未找到 Android 设备”;
  • ADB 不存在、启动失败、返回错误和超时有可理解的恢复提示;
  • 搜索期间禁止重复搜索,结束后按钮恢复;
  • 刷新后仍存在的已勾选设备保持勾选,已消失设备取消勾选;
  • 页面关闭后的迟到结果不会访问已销毁控件;
  • 不增加第三方依赖,不修改数据库和 Admin 接口;
  • 单元测试、离屏 Qt 测试、语法检查和 git diff --check 通过。

怎么验证

从 client/ 执行:

C:/Python310/python.exe -m py_compile src/android_device_service.py src/settings_ui_event.py
$env:QT_QPA_PLATFORM="offscreen"
C:/Python310/python.exe -m unittest discover -s test -p "test_*.py"
Remove-Item Env:QT_QPA_PLATFORM

真机验收:

  1. 连接一台 USB 或已经执行过 adb connect 的 Wi-Fi 设备;
  2. 从命令行确认 adb devices -l 能看到设备;
  3. 打开 Client 设置页并点击“搜索”;
  4. 核对设备号、连接方式、型号、Android 版本和状态;
  5. 拔掉或断开设备后再次搜索,确认设备从有效列表消失。

验收关闭

  • 用户于 2026-08-07 确认验收通过。
  • 本地归档状态已更新为“已完成”。
  • 验收归档提交:a6e3fe0。
## 基本信息 - 类型:需求 - 父级大工单:#1 - 所属 MVP / 版本:#2 / MVP - 阶段:3. Admin Mock/Gateway 闭环 - 依赖:#5、#11 - 当前状态:验收通过 ## 要解决什么 设置页已经有 Android 设备“搜索”按钮和设备表格,但按钮目前只发出 `searchRequested` 信号,没有实际执行 ADB 搜索,也没有把结果写回表格。 本任务让用户点击“搜索”后,能够在不阻塞 Qt 主线程的情况下列出当前 ADB 已识别的 USB 和 Wi-Fi Android 设备。 ## 做什么 / 不做什么 - 做: - 新增简单的 ADB 设备查询服务,执行 `adb devices -l`; - 解析设备号、连接方式、型号和 ADB 状态; - 对已连接设备查询 Android 版本,单台查询失败时仍保留该设备; - 使用 `QObject + moveToThread` 在后台执行搜索; - 搜索期间禁用设备管理命令,防止重复搜索; - 搜索成功、无设备、ADB 不可用和命令超时均显示明确的内联状态; - 搜索完成后通过现有 `set_android_devices()` 更新表格; - 页面关闭时断开回调并忽略迟到结果; - 使用标准库 `unittest` 覆盖解析、错误和离屏 Qt 线程行为。 - 不做: - 不自动安装、下载或升级 ADB; - 不修改系统 PATH; - 不执行 `adb connect`、保存或删除设备; - 不创建或共享 uiautomator2 Device 对象; - 不修改数据库、Admin 接口和 PDD 自动化流程; - 不增加第三方依赖。 ## 怎么做 1. 新增 `client/src/android_device_service.py`,通过可注入的命令执行器调用 ADB,方便单元测试。 2. 解析 `adb devices -l` 输出;带 `:` 的序列号显示为 Wi-Fi,其余显示为 USB。 3. 仅对状态为 `device` 的设备执行 `adb -s <serial> shell getprop ro.build.version.release`。 4. 在 `settings_ui_event.py` 增加搜索 Worker 和独立线程;Worker 只处理普通数据,不访问 QWidget。 5. 搜索结果由主线程转换为现有 `AndroidDeviceRow` 并更新模型;以设备序列号保持仍有效的勾选状态。 6. 复用设置页底部状态文字显示“正在搜索”“找到 N 台”“未找到”“搜索失败”等状态,不弹模态框。 7. ADB 命令设置有限超时,按钮快速重复点击只启动一次搜索。 8. 本次是现有局部交互补全,不调整页面布局,因此不制作 HTML 原型。 预计修改: - `client/src/android_device_service.py` - `client/src/settings_ui_event.py` - `client/src/settings_ui.py`(仅补充必要的无障碍名称或状态接口) - `client/test/test_android_device_service.py` - `client/test/test_settings_ui_event.py` ## 验收标准 - [x] 点击“搜索”会在后台执行 ADB 查询,Qt 主线程保持响应; - [x] USB 和 Wi-Fi 设备能正确区分并显示; - [x] 已连接设备显示型号、Android 版本和“已连接”状态; - [x] `offline`、`unauthorized` 等设备仍显示,并且不可勾选保存; - [x] 没有设备时表格保留空白占位行,并提示“未找到 Android 设备”; - [x] ADB 不存在、启动失败、返回错误和超时有可理解的恢复提示; - [x] 搜索期间禁止重复搜索,结束后按钮恢复; - [x] 刷新后仍存在的已勾选设备保持勾选,已消失设备取消勾选; - [x] 页面关闭后的迟到结果不会访问已销毁控件; - [x] 不增加第三方依赖,不修改数据库和 Admin 接口; - [x] 单元测试、离屏 Qt 测试、语法检查和 `git diff --check` 通过。 ## 怎么验证 从 `client/` 执行: ```powershell C:/Python310/python.exe -m py_compile src/android_device_service.py src/settings_ui_event.py $env:QT_QPA_PLATFORM="offscreen" C:/Python310/python.exe -m unittest discover -s test -p "test_*.py" Remove-Item Env:QT_QPA_PLATFORM ``` 真机验收: 1. 连接一台 USB 或已经执行过 `adb connect` 的 Wi-Fi 设备; 2. 从命令行确认 `adb devices -l` 能看到设备; 3. 打开 Client 设置页并点击“搜索”; 4. 核对设备号、连接方式、型号、Android 版本和状态; 5. 拔掉或断开设备后再次搜索,确认设备从有效列表消失。 ## 验收关闭 - 用户于 2026-08-07 确认验收通过。 - 本地归档状态已更新为“已完成”。 - 验收归档提交:`a6e3fe0`。
Author
Owner

工单已创建并同步到大工单 #1 和 MVP #2。现开始实施;工作区已有的 pdd_ui.py、ui_main.py 和未跟踪文件属于用户改动,本任务不会纳入提交。

工单已创建并同步到大工单 #1 和 MVP #2。现开始实施;工作区已有的 `pdd_ui.py`、`ui_main.py` 和未跟踪文件属于用户改动,本任务不会纳入提交。
Author
Owner

实施进度

已完成 ADB 查询服务、设置页后台 Worker、状态反馈、重复点击保护、勾选保持和关闭安全。

验证结果:

  • ADB 解析与错误测试通过;
  • 设置页离屏线程测试通过;
  • Client 全量 61 项测试通过;
  • 语法检查与 git diff --check 通过;
  • 当前电脑上的真实 ADB 搜索曾识别到 1 台 Wi-Fi 设备;设备随后断开,离屏真实按钮再次搜索正确显示“未找到 Android 设备”。

待人工验收:保持真机连接时,在可见界面核对设备号、型号、Android 版本和状态列。

## 实施进度 已完成 ADB 查询服务、设置页后台 Worker、状态反馈、重复点击保护、勾选保持和关闭安全。 验证结果: - ADB 解析与错误测试通过; - 设置页离屏线程测试通过; - Client 全量 61 项测试通过; - 语法检查与 `git diff --check` 通过; - 当前电脑上的真实 ADB 搜索曾识别到 1 台 Wi-Fi 设备;设备随后断开,离屏真实按钮再次搜索正确显示“未找到 Android 设备”。 待人工验收:保持真机连接时,在可见界面核对设备号、型号、Android 版本和状态列。
Author
Owner

已实现,等待验收

  • 功能提交:45fde81
  • 归档提交:03f91c2
  • 本地归档:docs/task/21-实现-android-设备搜索.md
  • Client 全量 61 项测试通过,语法检查与差异检查通过。
  • 未修改数据库、Admin 接口或依赖。

工单保持打开。请在 Android 设备保持连接时点击设置页“搜索”,人工核对表格中的连接方式、型号、Android 版本和状态。

## 已实现,等待验收 - 功能提交:`45fde81` - 归档提交:`03f91c2` - 本地归档:`docs/task/21-实现-android-设备搜索.md` - Client 全量 61 项测试通过,语法检查与差异检查通过。 - 未修改数据库、Admin 接口或依赖。 工单保持打开。请在 Android 设备保持连接时点击设置页“搜索”,人工核对表格中的连接方式、型号、Android 版本和状态。
ila closed this issue 2026-08-07 15:21:01 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: chengma/cmautobuy#21