168 lines
6.9 KiB
Plaintext
168 lines
6.9 KiB
Plaintext
钉钉打卡功能实现文档
|
||
====================
|
||
|
||
一、功能概述
|
||
-----------
|
||
实现了钉钉应用的自动化打卡功能,通过无障碍服务(AccessibilityService)自动完成以下操作:
|
||
1. 启动钉钉应用
|
||
2. 在钉钉首页查找并点击"打卡"按钮
|
||
3. 等待跳转到打卡页面
|
||
4. 在打卡页面点击"打卡"按钮完成打卡
|
||
|
||
二、实现方案
|
||
-----------
|
||
将钉钉打卡的业务逻辑直接集成到 AblService(无障碍服务)中,而不是使用 AblStepHandler。
|
||
这样做的优势:
|
||
- 避免 Handler 消息丢失:业务逻辑在无障碍服务中执行,即使主应用在后台也能正常运行
|
||
- 更可靠:无障碍服务是系统级服务,不会被轻易暂停
|
||
- 代码集中:所有打卡逻辑都在 AblService 中,便于维护
|
||
|
||
三、修改文件清单
|
||
---------------
|
||
|
||
1. app/src/main/java/com/fisherbone/fuzhu/abllib/AblService.java
|
||
2. app/src/main/java/com/fisherbone/fuzhu/activity/MainActivity.java
|
||
|
||
四、详细修改说明
|
||
---------------
|
||
|
||
【文件1】AblService.java
|
||
|
||
1. 添加导入
|
||
- import android.os.Handler;
|
||
|
||
2. 添加成员变量(第47-51行)
|
||
```java
|
||
// 钉钉打卡相关
|
||
private static final String DINGDING_PACKAGE = "com.alibaba.android.rimet";
|
||
private boolean isDingDingDakaStarted = false; // 是否已启动钉钉打卡流程
|
||
private int dingDingDakaStep = 0; // 打卡步骤:0-未开始,1-等待启动,2-点击首页打卡,3-点击打卡页面打卡
|
||
private Handler dingDingHandler = new Handler(); // 钉钉打卡专用 Handler
|
||
```
|
||
|
||
3. 修改 onAccessibilityEvent 方法(第155-162行)
|
||
在 TYPE_WINDOW_STATE_CHANGED 事件处理中添加钉钉窗口检测:
|
||
```java
|
||
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
|
||
String classname = event.getClassName().toString();
|
||
String packageName = event.getPackageName() != null ? event.getPackageName().toString() : "";
|
||
Log.e("TIAOSHI", "有弹出==22222" + "==classname==" + classname + ", packageName=" + packageName);
|
||
|
||
// 检测钉钉应用窗口,处理打卡流程
|
||
if (DINGDING_PACKAGE.equals(packageName) && isDingDingDakaStarted) {
|
||
handleDingDingDakaWindow(classname);
|
||
}
|
||
```
|
||
|
||
4. 添加核心方法
|
||
|
||
a) startDingDingDaka() - 启动打卡流程(第634-649行)
|
||
- 由 MainActivity 调用
|
||
- 设置 isDingDingDakaStarted = true
|
||
- 设置 dingDingDakaStep = 1(等待应用启动)
|
||
- 延迟2秒后执行步骤2
|
||
|
||
b) handleDingDingDakaWindow() - 处理钉钉窗口状态变化(第654-664行)
|
||
- 当检测到钉钉应用窗口变化时调用
|
||
- 根据当前步骤执行相应操作
|
||
|
||
c) executeDingDingDakaStep2() - 执行步骤2:点击首页打卡按钮(第669-703行)
|
||
- 查找并点击包含"打卡"文本的按钮
|
||
- 如果未找到,尝试"考勤打卡"、"工作"、"工作台"
|
||
- 点击成功后,延迟2秒执行步骤3
|
||
|
||
d) executeDingDingDakaStep3() - 执行步骤3:点击打卡页面打卡按钮(第708-724行)
|
||
- 当前已注释,等待用户根据实际需求实现
|
||
- 可以查找并点击"打卡"、"上班打卡"、"下班打卡"、"外勤打卡"、"立即打卡"等按钮
|
||
|
||
e) clickDakaButton() - 查找并点击包含指定文本的按钮(第729-744行)
|
||
- 获取根节点
|
||
- 调用 findAndClickDakaNode 递归查找
|
||
|
||
f) findAndClickDakaNode() - 递归查找并点击节点(第749-801行)
|
||
- 检查节点的文本和描述是否包含目标文本
|
||
- 如果节点可点击,直接点击
|
||
- 如果节点不可点击,使用 AblViewUtil.performViewClick() 自动查找可点击的父节点
|
||
- 递归查找子节点
|
||
|
||
g) resetDingDingDaka() - 重置打卡状态(第806-811行)
|
||
- 重置所有状态变量
|
||
- 清除所有延迟任务
|
||
|
||
【文件2】MainActivity.java
|
||
|
||
1. 修改 executeDingDingDaka() 方法(第640-654行)
|
||
将原来的 AblStepHandler 调用改为直接调用 AblService 的方法:
|
||
|
||
原代码:
|
||
```java
|
||
AblStepHandler.getInstance().setStop(false);
|
||
AblStepHandler.sendMsg(AblSteps.STEP_270);
|
||
```
|
||
|
||
新代码:
|
||
```java
|
||
AblService.getInstance().startDingDingDaka();
|
||
```
|
||
|
||
五、执行流程
|
||
-----------
|
||
|
||
1. 用户在 MainActivity 中点击"钉钉打卡"按钮
|
||
2. MainActivity.executeDingDingDaka() 被调用
|
||
3. 检查钉钉应用是否安装(使用多种方法:getPackageInfo、getLaunchIntentForPackage、queryIntentActivities)
|
||
4. 启动钉钉应用(优先使用 getLaunchIntentForPackage,失败则使用 LaunchHomeActivity)
|
||
5. 延迟1秒后调用 AblService.startDingDingDaka()
|
||
6. AblService 设置 isDingDingDakaStarted = true,dingDingDakaStep = 1
|
||
7. 延迟2秒后执行步骤2(executeDingDingDakaStep2)
|
||
8. 在钉钉首页查找并点击"打卡"按钮
|
||
9. 点击成功后,设置 dingDingDakaStep = 3,延迟2秒后执行步骤3
|
||
10. 在打卡页面查找并点击"打卡"按钮(当前已注释,需要根据实际需求实现)
|
||
11. 打卡完成后调用 resetDingDingDaka() 重置状态
|
||
|
||
六、关键日志标识
|
||
---------------
|
||
所有钉钉打卡相关的日志都使用 "TIAOSHI###" 作为标识,便于过滤和调试:
|
||
- "AblService: 启动钉钉打卡流程"
|
||
- "AblService: 钉钉打卡-步骤1完成,开始步骤2"
|
||
- "AblService: 钉钉打卡-步骤2: 查找并点击打卡按钮"
|
||
- "AblService: 钉钉打卡-步骤3: 在打卡页面点击打卡"
|
||
- "AblService: 找到匹配节点: ..."
|
||
- "AblService: 成功点击节点: ..."
|
||
|
||
七、注意事项
|
||
-----------
|
||
|
||
1. 无障碍服务必须已开启,否则 AblService.getInstance() 会抛出异常
|
||
2. 钉钉应用的包名是 "com.alibaba.android.rimet"
|
||
3. 步骤3(executeDingDingDakaStep3)当前已注释,需要根据实际打卡页面的UI实现
|
||
4. 所有延迟时间(2秒)可以根据实际情况调整
|
||
5. 如果找不到打卡按钮,会尝试多种可能的文本,如果都找不到则结束流程
|
||
|
||
八、待完善功能
|
||
-----------
|
||
|
||
1. executeDingDingDakaStep3() 方法当前已注释,需要根据实际打卡页面的UI实现
|
||
2. 可以添加更多的错误处理和重试机制
|
||
3. 可以添加打卡结果的通知或回调
|
||
|
||
九、测试建议
|
||
-----------
|
||
|
||
1. 确保无障碍服务已开启
|
||
2. 确保钉钉应用已安装
|
||
3. 在 MainActivity 中点击"钉钉打卡"按钮
|
||
4. 观察日志输出,确认每个步骤是否正常执行
|
||
5. 如果某个步骤失败,检查日志中的节点信息,调整查找逻辑
|
||
|
||
十、相关文件
|
||
-----------
|
||
|
||
- app/src/main/java/com/fisherbone/fuzhu/abllib/AblService.java
|
||
- app/src/main/java/com/fisherbone/fuzhu/activity/MainActivity.java
|
||
- app/src/main/java/com/fisherbone/fuzhu/abllib/utils/AblViewUtil.java(提供 performViewClick 方法)
|
||
- app/src/main/res/layout/activity_main.xml(包含"钉钉打卡"UI元素)
|
||
|
||
---
|
||
文档生成时间:2026-01-06
|