Files
lzwcai-terminal-worktool/交接文档.md
tanjianbin 22e6aff8c6 docs: 添加项目交接文档
添加 WorkTool 项目的详细交接文档,涵盖项目概述、技术栈、工程结构、运行流程、配置项、构建流程、调试方法及后续维护建议。该文档旨在帮助后续开发人员快速理解项目整体架构、关键代码位置和运行机制,便于后续维护与二次开发。
2026-05-08 17:26:43 +08:00

21 KiB
Raw Permalink Blame History

WorkTool 项目交接文档

本文档面向后续接手的开发人员,帮助快速理解 WorkTool 的整体架构、运行机制以及关键代码位置,便于后续维护与二次开发。


1. 项目概述

  • 项目名称WorkTool
  • 主要功能:依附于企业微信 / 微信运行的无人值守群管理机器人,通过无障碍服务和企业微信官方 SDK 实现自动收发消息、建群、拉人、踢人等能力。
  • 客户端形态Android 原生 APP需运行在一台专用手机上通过 WebSocket 与后端任务调度平台长连接通信。
  • 法规与安全:基于 Android 官方无障碍服务和企业微信官方 SDK无 Hook / 无 Root / 无内存修改,注意遵守腾讯运营规范与相关法律法规。

更多面向使用方的说明及 API 文档,可参考:


2. 技术栈与运行环境

  • 平台Android
  • 语言Kotlin + Java 混合
  • 构建工具Gradle使用仓库自带 gradlew
  • 最低支持版本:minSdkVersion 24
  • 目标版本:targetSdkVersion 30
  • 编译版本:compileSdkVersion 30
  • Java 版本:sourceCompatibility 1.8 / targetCompatibility 1.8
  • IDE 建议Android StudioArctic Fox 及以上版本均可正常打开)

涉及的关键第三方依赖(不完整列举):

  • 工具库:com.blankj:utilcodex(通过 com.blankj.utilcode.util.* 等类使用)
  • 日志:LogUtils(见 LogUtilsInit.kt
  • Toastcom.hjq:toastToastUtils
  • UI 组件:Material ComponentsMaterialAlertDialogBuilder)、QMUI 对话框
  • 网络通信:OkHttp WebSocketWebSocketManager.java
  • 埋点统计:友盟 (UMConfigure)TalkingData (TalkingDataSDK)
  • 企业微信 SDKlib_wwapi-*.aar(位于 app/libs/

3. 工程结构总览

根目录主要文件与模块:

  • app/:主 APP 工程业务逻辑、UI、无障碍自动化、与后端通信等全部在此
  • baselibrary/:基础 UI / Adapter 等通用组件
  • floatwindow/:悬浮窗相关实现
  • BACKEND_PROTOCOL.md:客户端与后台 WebSocket 协议说明
  • README.md:面向使用方的简要说明与版本更新记录

多模块声明见:

3.1 app 模块结构

路径:app/src/main/java/org/yameida/worktool/

主要包与职责:

  • activity/
    • ListenActivity主控制面板配置链接号robotId、后端 host、开关无障碍与悬浮窗是日常运维主要入口。
    • LoginActivity:登录相关界面。
    • SettingsActivity / SettingsAdvanceActivity:基础及高级设置。
    • AccessibilityGuideActivity / FloatViewGuideActivity:权限引导页面。
    • BrowserActivityGetScreenShotActivity:辅助操作页面。
  • service/
    • WeworkService:无障碍服务实现,负责监控和操作企业微信界面,是自动化的核心。
    • WeworkController:统一调度控制,无障碍操作入口,管理循环任务状态。
    • WeworkLoopImpl / WeworkOperationImpl / WeworkInteractionImpl / WeworkGetImpl:对企业微信不同操作的具体实现(循环拉取任务、执行发送消息、拉群、获取信息等)。
    • PlayNotifyService / PlayNotifyManager:前台服务与通知控制,保障机器人在前台或长时间运行。
    • GlobalMethod.kt / MyLooper.kt:封装通用操作和循环执行器。
  • utils/
    • 网络相关:HttpUtil.ktREST 接口访问)、OkHttpUtil.ktWebSocketManager.java
    • 无障碍与权限:AccessibilityUtil.ktAccessibilityExtraUtil.ktPermissionHelper.ktFlowPermissionHelper.ktPermissionPageManagement.java
    • 悬浮窗:FloatWindowHelper.kt,配合 floatwindow 模块实现全局悬浮按钮。
    • 屏幕与截图:capture/ 包下的 ScreenCaptureUtilScreenCaptureUtilByMediaProMediaProjectionHolder.kt 等。
    • 配置与缓存:CacheUtil.ktPropUtil.ktHostTestHelper.kt
    • 其他工具:RegexHelper.ktRuntimeUtil.ktWeworkRoomUtil.ktWeworkTextUtil.kt 等。
  • model/
    • network/:与后端通信的返回体,例如 CheckUpdateResult.javaGetMyConfigResult.java
    • operation/:执行结果封装,如 SelectResult.kt
    • WeworkMessageBean.java / WeworkMessageListBean.ktWebSocket 消息封装,与 BACKEND_PROTOCOL.md 一一对应。
    • AppUpdate.javaMyConfigBean.kt 等:应用更新 / 机器人配置相关模型。
  • notification/:通知栏相关封装(PlayNotifyManager.kt)。
  • config/:全局异常处理(GlobalException.java)。
  • observer/:文件监听等辅助(MultiFileObserver.java)。
  • 顶层文件:
    • MyApplication.kt:全局 Application完成 SDK 初始化、前台服务启动等。
    • Constant.kt:全局常量与配置(可持久化到 SPUtils)。
    • Demo.kt:示例或测试代码(如有使用可再确认)。

3.2 baselibrary 模块

路径:baselibrary/

  • 主要保存通用 UI 组件与 Adapter例如 RvSimpleAdapterRvViewHolder
  • 资源文件中包含通用 stylesstrings 等。
  • 项目中作为 app 的依赖模块,无业务逻辑。

3.3 floatwindow 模块

路径:floatwindow/

  • 浮窗管理:FloatWindowManager.ktBaseFloatWindow.javaDefaultFloatService.kt
  • 监听器:listener/ 包下 FloatWindowListener.ktOnClickListener.kt 等。
  • 视图:view/HiderView.java 与相关布局、图片资源。
  • app 提供悬浮窗入口、暂停 / 启动机器人等操作。

4. 运行流程与关键逻辑

4.1 App 启动流程

入口类:

  • AndroidManifest.xml 中配置 MyApplication 作为 application,主 Activity 为登录或 Listen 页(视具体配置而定)。
  • MyApplication.kt 负责:
    • 初始化 Utils、日志配置(LogUtilsInit)、Gson 代理。
    • 初始化 ToastUtils
    • 初始化友盟埋点(UMConfigure),通过 SPUtilsuminit 标记隐私协议同意状态。
    • 初始化 TalkingDataTalkingDataSDK.init(...)Constant.robotId 作为渠道维度之一。
    • 初始化企业微信 SDKIWWAPIUtil.init(this))。
    • 初始化应用更新框架(UpdateAppUtils.init(this))。
    • 启动前台通知(PlayNotifyManager.show())。
    • 设置全局异常捕获(GlobalException),异常时自动重启。

4.2 ListenActivity 配置流程

核心界面:ListenActivity.kt

主要职责:

  • 展示并编辑链接号(robotId
    • 文本框 et_channel 显示当前 Constant.robotId
    • 点击“保存”按钮:
      • 将输入写入 Constant.robotId(内部通过 SPUtils 持久化)。
      • 发送广播通知 Constant.WEWORK_NOTIFY,类型为 modify_channel
      • 调用 HttpUtil.getMyConfig(toast = false) 拉取机器人配置。
      • 将链接号上报给友盟 MobclickAgent.onProfileSignIn(channel)
  • 配置 WebSocket host
    • 文本 tv_host 显示 Constant.host
    • 点击:弹出历史 host 列表(来自 SPUtilshost_list),支持一键切换并调用 HostTestHelper.testWs() 进行连通性检测。
    • 长按:弹出编辑对话框,支持新增 / 删除 host新增时校验是否符合 ws://wss:// 开头格式。
  • 权限开关:
    • 无障碍开关 sw_accessibility
      • 校验是否填写链接号。
      • 校验是否已开启系统无障碍;如未开启,跳转到引导页 AccessibilityGuideActivity 或系统设置。
      • 如检测到 Hook / Root 环境,进行风险提示并控制运行。
      • 关闭时调用 WeworkController.weworkService.disableSelf()(在部分 ROM 上会转跳到系统设置)。
    • 悬浮窗开关 sw_overlay
      • 开启时跳转 FloatViewGuideActivity 引导授权。
      • 已授权时显示悬浮窗(FloatWindowHelper.showWindow())或引导前往权限设置页。
  • 环境检测:
    • 设备信息、Root 状态、Hook 状态写入 SPUtils,用于后续分析。
    • 检查企业微信当前版本是否在 Constant.AVAILABLE_VERSION 列表内,给出“已适配 / 可能存在兼容性问题”等提示。
  • 初始化数据:
    • initData 中设置默认 Constant.robotIdConstant.host(可以视需要调整或移除默认值)。
    • 调用 HttpUtil.getMyConfig(toast = false) 拉取机器人配置。
    • 调用 CacheUtil.autoDelete() 清理旧缓存。

4.3 与后端的通信

WebSocket 链接:

  • WebSocket 地址统一由 Constant.getWsUrl() 生成,格式为:<host>/webserver/wework/<robotId>
    • 默认 host 在 Constant.DEFAULT_HOST 中配置:ws://8.166.130.74:18680
    • host 与 robotId 最终都持久化在 SPUtils 中,方便修改。
  • 具体 WebSocket 管理由 WebSocketManager.java 实现:
    • 维护 WebSocket 连接、心跳(每 5 秒一次)、自动重连。
    • 发送和确认消息(WeworkMessageListBean 封装),写入日志。
    • 断线时关闭新消息接收(WeworkController.setEnableLoopRunning(false)),重连成功后再恢复。
    • 当长时间连接正常且未开启截屏模式时,如果检测到长时间未重连且仍在运行,会通过 Toast 提示“机器人运行中 请勿人工操作手机~”。

协议格式:

  • 完整协议说明见 BACKEND_PROTOCOL.md
    • 连接 URL 格式、心跳机制。
    • WeworkMessageListBeanWeworkMessageBean 的字段含义。
    • 常用指令类型(如 203 发送消息、218 推送文件、505 获取最近聊天列表、101 接收消息列表等)。
    • 执行结果回调、错误码定义。
  • 代码中 typesocketType 等字段与文档一一对应,建议修改协议前同时修改此文档与对应模型类。

4.4 自动化执行流程(企业微信侧)

高层流程(简化):

  1. 后端下发任务(通过 WebSocket
  2. 客户端解析为 WeworkMessageBean / WeworkMessageListBean
  3. WeworkController 调度对应的 Wework*Impl 实现执行操作:
    • 打开企业微信指定页面。
    • 定位目标群 / 联系人。
    • 根据控件树执行点击、输入文本、长按、转发等操作。
  4. 执行完成后,将结果封装回 WebSocket 消息上报服务端,包含成功 / 失败列表、错误原因等。

关键依赖:

  • 无障碍服务:WeworkService + AccessibilityUtil / AccessibilityExtraUtil
  • 文本匹配与房间识别:RegexHelperWeworkRoomUtilWeworkTextUtil
  • 循环任务:MyLooperWeworkLoopImpl

5. 配置项与敏感信息

5.1 host 与 robotId

相关代码:

说明:

  • Constant.host
    • 默认值:DEFAULT_HOST = "ws://8.166.130.74:18680"
    • 通过 SPUtils 持久化,键为 "host"
    • 可在 ListenActivity 中通过 host 列表 / 编辑弹窗进行修改。
    • 业务上可视为“后端 WebSocket 网关地址”,如需要更换环境(测试 / 生产)时重点关注。
  • Constant.robotId
    • 通过 ListenActivity 的输入框配置。
    • 底层持久化键为 "robotId",同时兼容历史 "LISTEN_CHANNEL_ID"
    • 后端一般将其视为“链接号 / 机器人唯一 ID”用于区分不同设备 / 账号。

注意事项:

  • 在更改默认 host 或引导用户填写 robotId 时,需要与后端保持一致(确保后台任务调度平台识别该 robotId
  • 如需要支持多环境(测试 / 预发 / 生产),可以在现有 host 列表机制上扩展 UI 与配置管理。

5.2 企业微信兼容版本

相关代码:

  • Constant.ktAVAILABLE_VERSIONAVAILABLE_VERSION_MAP
  • ListenActivity 中通过 AppUtils.getAppInfo(Constant.PACKAGE_NAMES)?.versionName 获取企业微信版本。

说明:

  • AVAILABLE_VERSION 列出了当前已适配的企业微信版本号(例如 4.1.84.1.94.1.10 等)。
  • AVAILABLE_VERSION_MAP 用于将版本号映射为内部的整数版本,用于兼容性判断。
  • 当检测到企业微信版本不在列表内时,会提示“可能存在部分兼容性问题”,但仍允许使用。

后续维护建议:

  • 当企业微信版本升级后,需要:
    • 手动测试各项自动化功能。
    • 若确认兼容,将新版本号加入 AVAILABLE_VERSIONAVAILABLE_VERSION_MAP
    • 如需要针对特定版本调整逻辑,可结合 Constant.version 做分支处理。

5.3 统计与第三方 SDK key

相关代码:

说明:

  • 友盟统计:
    • val key = "6284a3a3d024421570f97c3c"
    • 通过 UMConfigure.preInit / UMConfigure.init 初始化。
    • 隐私协议同意状态通过 SPUtils"uminit" 字段控制。
  • TalkingData
    • TalkingDataSDK.init(this, "80E9C84E39904DAFB28562910FF7C86C", getString(R.string.app_name) + "_master", Constant.robotId)
    • 依赖 Constant.robotId 作为渠道维度。

接手后如需更换统计账号或关闭统计:

  • 调整或移除相应初始化代码。
  • 同时评估对现有数据分析的影响,必要时与产品 / 运维同步。

6. 构建、打包与发布流程

6.1 本地开发环境搭建

  1. 克隆仓库到本地:
    • 建议完整克隆含子模块(当前项目无 Git 子模块,仅多 module
  2. 使用 Android Studio 打开仓库根目录。
  3. 确保本地已安装:
    • JDK 8或 Android Studio 自带 JDK
    • Android SDK 30 及对应 Build Tools。
  4. 首次打开时,按 IDE 提示同步 Gradle等待依赖下载完成。

6.2 常用构建命令

在项目根目录下,可以使用仓库自带 Gradle Wrapper

  • 编译 Debug 包:

    ./gradlew assembleDebug
    
  • 编译 Release 包:

    ./gradlew assembleRelease
    

注意:

  • app/build.gradlerelease 构建类型启用了混淆:
    • minifyEnabled true
    • 混淆配置文件:proguard-android-optimize.txt(默认)与 app/proguard-rules.pro
  • 签名配置可能未在仓库中直接提供(如使用本地 keystore),如需正式发布包,请向原维护人员或运维团队索取签名文件与配置。

6.3 打包注意事项

  • 由于集成了企业微信 SDKlibs/lib_wwapi-*.aar)及多个三方 SDK混淆配置需要保持当前状态避免将关键类混淆导致运行崩溃。
  • 如新增依赖,请同步更新 proguard-rules.pro
  • Release 包上线前建议至少在以下维度自测:
    • 不同 Android 版本(特别是 API 24~30
    • 不同厂商 ROM华为、小米、OPPO、VIVO 等)的无障碍与后台保活行为。
    • 至少一种已适配的企业微信版本。

7. 日常调试与常见问题

7.1 日志查看

  • 项目统一使用 LogUtils 输出日志,初始化在 LogUtilsInit 中。
  • 日志输出位置、格式可在 LogUtilsInit.kt 中调整。
  • 联调时建议:
    • 在关键流程WebSocket 收发、无障碍执行)增加必要的日志。
    • 结合后端日志与手机本地日志定位问题。

7.2 无障碍与权限问题

常见现象:

  • 无法自动跳转 / 点击:
    • 检查系统无障碍设置中是否已为 WorkTool 授权。
    • 检查是否被 ROM 的“电池优化 / 后台保护”策略限制。
  • 悬浮窗不显示:
    • 检查“悬浮窗权限”是否开启。
    • 检查 FloatWindowHelper.showWindow() 是否被调用。

相关工具类:

  • PermissionHelper:无障碍权限判断与相关操作。
  • FlowPermissionHelper:后台启动、悬浮窗等权限判断。
  • PermissionPageManagement:跳转至系统设置页面。

7.3 WebSocket 连接异常

排查步骤:

  1. 在 ListenActivity 中确认 hostrobotId 配置正确。
  2. 使用 HostTestHelper.testWs()ListenActivity 操作 host 时自动调用)测试连通性。
  3. 查看 WebSocketManager 日志,确认是否存在频繁断线重连。
  4. 确认服务端配置与 BACKEND_PROTOCOL.md 版本一致。

进一步建议(针对日志中偶发 Connection closed 场景):

  • 现象判定:
    • 若出现“断开后 1~2 秒内自动重连成功,且同一 clientId 可继续收发消息”,通常是短时网络抖动或网关空闲回收,不一定是严重故障。
    • 若出现“周期性断开(如每几分钟一次)”或“重连失败持续告警”,优先排查配置问题。
  • 归因方法(客户端 / 服务端 / 网关):
    • 客户端Android补充日志WeworkService.EchoWebSocketListeneronClosing/onClosed/onFailure 打印 codereasonthrowable
    • 服务端补充日志:在 WebSocket Handler 的关闭与异常回调中打印 clientIdsessionId、关闭码、异常栈。
    • 网关层补充日志Nginx / LB 记录 upstream 连接关闭原因与空闲超时触发记录。
    • 通过同一时间窗口对齐三端日志,判断“谁先发起关闭、关闭码是什么、是否有网络异常”。
  • 常见根因:
    • 手机网络切换Wi-Fi/移动网络)或弱网导致 TCP 断开。
    • 网关 / 反向代理空闲超时过短,主动关闭 WebSocket。
    • 心跳机制仅业务层保活,未启用 WebSocket ping导致中间设备误回收长连接。
    • Android 省电策略导致后台网络能力受限。
  • 建议优化项(按优先级):
    • 客户端统一复用 OkHttpClient,并开启 pingInterval(建议 20~30 秒)。
    • 网关与服务端 idle timeout 应明显高于心跳周期(建议至少 30~60 秒)。
    • 重连策略增加“指数退避 + 抖动”,避免批量设备同时重连。
    • 在运维侧统计“每设备每小时断线次数、重连耗时、连续失败次数”,作为健康度指标。

相关代码入口:

  • WebSocket 管理:app/src/main/java/org/yameida/worktool/utils/WebSocketManager.java
  • 监听与回调:app/src/main/java/org/yameida/worktool/service/WeworkService.kt

8. 后续可扩展与注意事项

  • 协议变更:
    • 修改 WebSocket 协议或新增指令类型时,需同时更新:
      • WeworkMessageBean / WeworkMessageListBean 数据结构。
      • Wework*Impl 中对新指令的处理逻辑。
      • 文档 BACKEND_PROTOCOL.md
  • 新企业微信版本适配:
    • 新版本上线后,需实机测试高频功能。
    • 确认后更新 Constant.AVAILABLE_VERSION 及相关逻辑。
  • 安全与合规:
    • 严禁在代码中硬编码任何生产环境账号密码。
    • 涉及数据采集、上传时注意隐私合规(特别是好友信息、聊天内容等)。

9. 交接建议

建议接手同学优先按以下顺序熟悉项目:

  1. 阅读 README 与本交接文档,理解整体定位与功能。
  2. 在测试环境跑通完整链路:
    • 编译安装 APP。
    • 配置测试后端 host 与 robotId。
    • 打开无障碍与悬浮窗权限。
    • 使用后台调度平台下发几种典型任务(发送文本、发送图片、获取最近聊天列表等)。
  3. 深入阅读核心代码:
    • MyApplication(启动流程)。
    • ListenActivity(配置入口)。
    • WeworkService + WeworkController + Wework*Impl(自动化执行)。
    • WebSocketManager + 协议模型类(通讯层)。
  4. 根据实际需要再进一步梳理业务细节与扩展点。

如后续对具体模块或逻辑有疑问,可在对应类文件中逐步补充更细的内部文档或注释,并与团队同步更新本交接文档。