# 设备 Agent(DeviceAgent) 装在每台 Android 手机上的**设备端补位 App**,配合 [auto_control](https://gitea.butubb.cn/butubb/auto_control) 平台使用。 平台通过 **adb** 驱动设备;这个 App 负责三件 adb 干不好/干不了的事: | 能力 | 为什么 adb 不行 | 入口 | |------|----------------|------| | **剪贴板注入** | Android 10+ 只有**有焦点**的应用能写剪贴板,shell/后台写会被系统静默丢弃 | `ClipActivity`(透明 Activity,adb 拉起) | | **应用分发(商店)** | `adb install` 会被 MIUI 的「USB 安装」拦成 `USER_RESTRICTED`;**由设备上的 App 自己调系统安装器**走的是普通安装流程,不触发那道拦截 | `MainActivity`(商店界面,自己联网拉清单) | | **设备身份显示** | 以前要把 HTML 大字页推给设备浏览器打开,依赖浏览器 | `InfoActivity`(全屏大字,adb 拉起) | ## 接口契约 **平台的接口协议见 `../auto_control/doc/DEVICE_AGENT.md`**(那是两个仓库共享的契约; 改协议必须同时改两边)。本仓库里也留了一份副本:[INTERFACE.md](INTERFACE.md)。 ## 快速开始 ```bash # 1. 构建(需要 JDK 17 + Android SDK;也可以用 Android Studio 直接打开) ./gradlew assembleDebug # 2. 装到设备(平台用网络 adb 管理设备,serial 形如 IP:5555) adb -s 192.168.20.100:5555 install -r app/build/outputs/apk/debug/app-debug.apk # 3. 一次性配置平台地址与令牌(不用在手机上手输) adb -s 192.168.20.100:5555 shell am start -n com.example.deviceagent/.ConfigActivity \ --es server "http://192.168.20.220:18050" --es token "<平台面板里的设备令牌>" # 4. 自检:确认装上了、看是哪一版 adb -s 192.168.20.100:5555 shell am start -n com.example.deviceagent/.PingActivity adb -s 192.168.20.100:5555 shell cat /sdcard/Android/data/com.example.deviceagent/files/status.json # 5. 手动试试剪贴板注入 adb -s 192.168.20.100:5555 shell am start -n com.example.deviceagent/.ClipActivity \ --es text_b64 "$(printf '测试中文' | base64)" # 6. 让设备显示自己的身份大字页 adb -s 192.168.20.100:5555 shell am start -n com.example.deviceagent/.InfoActivity \ --es name "A08" --es ip "192.168.20.100" --es serial "192.168.20.100:5555" \ --es server "http://192.168.20.220:18050" ``` 然后用手机打开 App 图标 → 就是应用商店(前提是平台侧已启用设备端商店并给了令牌)。 ## 权限说明 只申请三个,都是必需的: - `INTERNET` —— 从平台拉应用清单、下载 APK - `REQUEST_INSTALL_PACKAGES` —— 调系统安装器装应用(**首次会引导去系统设置里授权**) - `ACCESS_NETWORK_STATE` —— 判断有没有网 **不需要 root、不需要设备管理员、不常驻后台、不申请任何读取隐私的权限。** ## 代码结构 ``` app/src/main/java/com/example/deviceagent/ MainActivity.kt 应用商店主界面(清单/下载/调安装器/回报) ClipActivity.kt 剪贴板注入(透明,等窗口获得焦点后再写) InfoActivity.kt 设备身份全屏大字页 ConfigActivity.kt 一次性配置下发(平台用 adb 推地址+令牌) PingActivity.kt 自检(版本/指纹/配置状态,写 logcat + status.json) Api.kt 平台接口客户端(HttpURLConnection,无第三方库) Prefs.kt 配置存储 + 设备指纹(getprop ro.serialno) ``` 刻意**只依赖 androidx.core**(就为了 FileProvider):HTTP 用 `HttpURLConnection`、 JSON 用系统内置的 `org.json`,依赖越少越不容易被构建问题绊住。