Skip to content

loongj-code/ZenTasker

Repository files navigation

ZenTasker

ZenTasker 是一个基于 Shizuku 的 Android 本地自动化调度应用,使用 AlarmManager 做链式唤醒,用 Jetpack Compose 提供控制台界面,并通过 Shell + uiautomator dump 完成基础自动化执行。

项目目标很明确:不用无障碍常驻,不开前台服务,把任务注册、唤醒、执行、重调度全部收敛在一个低常驻成本的本地自动化流程里。

开源协议

本项目采用 GNU General Public License v3.0,许可证全文见根目录 LICENSE

除非另有说明,项目源码 Copyright (C) 2026 loong,并按 GPL-3.0-only 发布。这意味着:

  • 你可以使用、修改和分发本项目代码
  • 如果你分发修改版或基于本项目的衍生项目,必须继续以 GPL-3.0 公开其对应源码
  • 本项目按“无担保”方式提供

主要能力

  • 基于 AlarmManager 的单线链式调度,只注册最近一次可执行任务
  • 支持开机后与应用升级后的自动重建调度
  • 支持任务脚本可视化编辑和 JSON 编辑
  • 支持 shellswipesleepfind_and_tap 四类动作
  • find_and_tap 基于 uiautomator dump 解析节点文字或 content-desc 后点击中心点
  • 支持 everydayworkday_only 两种触发条件
  • 提供 Shizuku、日历权限、电池优化白名单状态面板
  • 提供干跑测试和应用内日志查看

当前界面

应用当前包含 3 个主页面:

  • Dashboard:权限状态、下一次任务、调度预览、重载注册、干跑测试
  • Editor:任务表单编辑和 JSON 编辑
  • Logs:查看与清空执行日志

调度模型

ZenTasker 采用“只调度下一个任务”的链式模型:

  1. 从本地配置读取全部 jobs
  2. 计算当前时间之后最近且满足条件的一个 job
  3. 使用 setExactAndAllowWhileIdle 注册闹钟
  4. 闹钟触发后由 TaskReceiver 拉起执行
  5. 执行结束后立即重新计算并注册下一次任务

如果设备未授权精确闹钟,应用会降级为普通调度,并在界面上显示对应状态。

技术栈

  • Kotlin
  • Jetpack Compose
  • Kotlin Coroutines
  • Gson
  • Shizuku API 13.1.5
  • Android AlarmManager / BroadcastReceiver / CalendarContract

开发环境要求

  • Android Studio 新版本
  • JDK 11
  • Android SDK:
    • compileSdk = 36
    • targetSdk = 36
    • minSdk = 26

本地构建

Debug

.\gradlew.bat assembleDebug

单元测试

.\gradlew.bat testDebugUnitTest

Release

Release 构建要求提供签名配置。可以二选一:

  1. 在项目根目录创建 keystore.properties
  2. 配置环境变量:
    • ZEN_TASKER_STOREFILE
    • ZEN_TASKER_STOREPASSWORD
    • ZEN_TASKER_KEYALIAS
    • ZEN_TASKER_KEYPASSWORD

可参考项目中的 keystore.properties.example

.\gradlew.bat assembleRelease

GitHub Actions Release

本仓库的 release 构建已经支持从环境变量读取签名配置,所以在 GitHub Actions 中只需要恢复 keystore 文件并注入这些 secrets:

  • SIGNING_KEYSTORE_BASE64
  • ZEN_TASKER_STOREPASSWORD
  • ZEN_TASKER_KEYALIAS
  • ZEN_TASKER_KEYPASSWORD

其中 SIGNING_KEYSTORE_BASE64.jks 文件的 Base64 内容。Windows PowerShell 可这样生成:

[Convert]::ToBase64String([IO.File]::ReadAllBytes("zentasker-release.jks"))

工作流文件是 .github/workflows/release.yml,支持两种触发方式:

  • 推送 tag,例如 v1.1.0,自动构建签名 APK 并发布 GitHub Release
  • 在 Actions 页面手动运行,构建并上传 APK artifact

示例:

git tag v1.1.0
git push origin v1.1.0

设备运行前提

应用要正常执行自动化任务,至少需要满足这些条件:

  • 已安装并启动 Shizuku
  • 已向 ZenTasker 授予 Shizuku 权限
  • 建议关闭电池优化
  • Android 12+ 建议授权精确闹钟
  • 如果使用 workday_only,建议授予日历读取权限

workday_only 的判断逻辑如下:

  • 优先读取系统日历事件标题
  • 命中 “班” 或 “调休” 视为工作日
  • 命中 “休” 或 “节假日” 视为非工作日
  • 如果没有日历权限或没有匹配事件,则回退到普通周一到周五判断

配置文件

运行时配置不是直接读取仓库内文件,而是保存在应用私有目录中的 config.json。首次启动时会自动写入一份默认模板。

当前任务模型示例:

{
  "jobs": [
    {
      "job_id": "morning_clock_in",
      "job_name": "上班打卡",
      "trigger_time": "08:50",
      "condition": "workday_only",
      "tasks": [
        {
          "action": "shell",
          "cmd": "input keyevent 224",
          "desc": "点亮屏幕"
        },
        {
          "action": "sleep",
          "duration": 1000,
          "desc": "等待系统就绪"
        },
        {
          "action": "swipe",
          "x1": 500,
          "y1": 2000,
          "x2": 500,
          "y2": 500,
          "duration": 300,
          "desc": "滑动解锁"
        },
        {
          "action": "find_and_tap",
          "target_text": "工作台",
          "timeout_ms": 15000,
          "retry_interval_ms": 2000,
          "desc": "查找并点击工作台"
        }
      ]
    }
  ]
}

说明:

  • job_id 需要唯一
  • trigger_time 格式为 HH:mm
  • condition 当前仅支持 everydayworkday_only
  • JSON 字段名使用 snake_case
  • 表单编辑和 JSON 编辑都会写回本地 config.json
  • app/src/main/assets/jobs.json 当前更接近示例素材,不是主要运行时数据源

支持的任务动作

shell

直接通过 Shizuku UserService 执行 Shell 命令。

关键字段:

  • cmd
  • timeout_ms 可选

swipe

本质上会转换成:

input swipe x1 y1 x2 y2 duration

关键字段:

  • x1
  • y1
  • x2
  • y2
  • duration 可选
  • timeout_ms 可选

sleep

挂起协程等待指定毫秒数。

关键字段:

  • duration

find_and_tap

执行流程:

  1. uiautomator dump /data/local/tmp/window_dump.xml
  2. cat /data/local/tmp/window_dump.xml
  3. 匹配节点 textcontent-desc
  4. 解析 bounds
  5. 计算中心点并执行 input tap

关键字段:

  • target_text
  • timeout_ms 可选
  • retry_interval_ms 可选

日志与排查

  • 应用日志保存在私有文件 zentasker_logs.txt
  • 日志页会读取最近的日志内容
  • 干跑测试会按当前选中的 job 顺序执行其全部任务并记录结果

常见问题优先检查:

  • Shizuku 是否已运行
  • ZenTasker 是否已获得 Shizuku 权限
  • 精确闹钟是否可用
  • 电池优化是否放行
  • workday_only 是否因日历规则或周末判断被跳过
  • find_and_tap 目标文字是否真的出现在当前界面节点树里

项目结构

app/src/main/java/com/zentasker
├─ executor      # Shizuku 远程执行与智能点击
├─ scheduler     # 条件判断、链式调度、广播接收器
├─ script        # JSON 配置解析与模型
├─ ui            # Compose 页面与组件
└─ utils         # 日志等工具

已实现的关键模块

  • ScheduleManager:计算下一次任务并注册系统闹钟
  • TaskReceiver:执行任务并在结束后续约下一次调度
  • RescheduleReceiver:开机或应用升级后重建调度
  • SmartExecutor:封装 Shizuku UserService 和任务动作执行
  • JobScriptParser:本地配置读写、JSON 校验与默认配置注入

注意事项

  • 这是一个强依赖系统能力与 Shizuku 运行状态的本地自动化项目
  • 不使用无障碍服务,不提供前台服务常驻
  • find_and_tap 依赖界面文字或无障碍描述,目标控件不可见时会失败
  • 节假日判断依赖系统日历事件命名习惯,适合本地自定义环境,不适合作为通用法定节假日服务

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors