# tvzenbox **Repository Path**: geek0070/tvzenbox ## Basic Information - **Project Name**: tvzenbox - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-10-05 - **Last Updated**: 2026-10-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TvZenBox(禅盒 · TV 版) 跑在 **已 root 的 Android 9 电视盒子**上的自律关机工具:开机满设定时长自动关机;关机后 10 分钟内再开机判为「作弊」,很快再次关机;**断网不判作弊**、只按开机时长兜底,防止「开机即关」。 形态是 **APK 壳 + shell 守护**:APK 管遥控界面与配置,真正的计时/判罚/关机逻辑在 `/sdcard/tvzenbox/*.sh`,由开机自启钩子以 root 拉起(真机 SlimBox ROM 用 `/data/media/0/init.d/tvzenbox`;标准 su 盒子仍可用 `/system/etc/init/tvzenbox.rc`)。 - 设计文档:`TvZenBox-DESIGN.md` 任务清单:`TvZenBox-TASKS.md` 需求:`AR-TvZenBox.md` - 参考:`参考/14adb学习.md` UI 基线:`imgs/UI1.png` 修复记录:`fix-error-report.md` --- ## 1. 目录结构 | 路径 | 作用 | | --- | --- | | `app/` | Android 工程(Kotlin)。APK 内置 `assets/scripts/*.sh`、`assets/scripts/tvzenbox-bootstrap.sh`、`assets/system/tvzenbox.rc` | | `app/src/main/assets/scripts/` | **设备侧守护脚本的唯一源文件**(会被 APK 内置并部署到 `/sdcard/tvzenbox/`) | | `app/src/main/assets/system/tvzenbox.rc` | 自启声明 rc 源文件(部署脚本使用此副本) | | `system/etc/init/tvzenbox.rc` | 手动安装/参考用的 rc 副本 | | `tests/` | PC 上跑的脚本测试套件(虚拟时钟,`sh tests/run_tests.sh`) | | `deploy/` | **本机侧**部署/卸载:`deploy.bat` / `uninstall.bat` 为入口,实际逻辑在 `deploy.py` / `uninstall.py` | | `deploy/initd-tvzenbox.sh` | 真机(SlimBox ROM)开机自启钩子源文件 | | `build.bat` | Windows 一键构建 APK | > 仓库根目录的 `scripts/` 已移除;所有守护脚本统一放在 `app/src/main/assets/scripts/`,部署脚本也从这里读取。 --- ## 2. 前置条件 1. **Android 9 电视盒子**(Android 9 以上兼容未验证)。 2. **自启部署需要 root 能力**:标准 root 盒子有 `su`,App 可尝试自动写 `/system/etc/init/tvzenbox.rc`;本项目真机是 **adb root 且无 `su`**,自启走 **SlimBox ROM 的 init.d 钩子**(`/data/media/0/init.d/tvzenbox`),必须用受权 adb 部署一次。 3. **盒子开启无线调试**(`adb` 默认端口 5555);或用 USB 连接。 4. 本机有 `adb`(在 `PATH` 中)。 5. 要**构建** APK 时还需 JDK 17 与 Android SDK(脚本里已有默认路径,可用环境变量覆盖)。 --- ## 3. 使用方法 ### 3.1 最简流程(推荐,Windows 一键) ```bat REM 连接、构建、安装 APK、释放脚本、装引导链、装 rc、装 ROM init.d 钩子、校验 deploy\deploy.bat -H 192.168.1.100 REM 指定 IP/端口,跳过重新构建: deploy\deploy.bat -H 192.168.1.100 --skip-build REM 只打印将执行的命令: deploy\deploy.bat -H 192.168.1.100 --dry-run --skip-build ``` > `deploy.py` 会执行:`adb connect` → `assembleDebug`(可跳过)→ `adb install -r -g` → push 脚本到 `/sdcard/tvzenbox/` → push 引导脚本到 `/data/local/tvzenbox/` → 安装 rc → **安装 `/data/media/0/init.d/tvzenbox`(755)** → 校验。 > 部署完成后重启盒子,守护即会自动拉起。 ### 3.2 手动安装(备选,不依赖 `deploy.bat`) ```bash # ① 连接盒子(无线调试;IP 换成你的盒子) adb connect 192.168.1.100:5555 # ② 安装 APK adb install -r app/build/outputs/apk/debug/app-debug.apk # ③ 创建设备侧工作目录 adb shell mkdir -p /sdcard/tvzenbox/logs /sdcard/tvzenbox/run /sdcard/tvzenbox/system # ④ 释放守护脚本(源在 app/src/main/assets/scripts/;部署脚本会做 CRLF 归一) for f in config.sh funcs.sh timekeep.sh guard.sh init.sh tvzenbox-bootstrap.sh; do adb push app/src/main/assets/scripts/$f /sdcard/tvzenbox/$f done # ⑤ 部署开机引导桥接(等 /sdcard 就绪后拉起 init.sh) adb shell mkdir -p /data/local/tvzenbox adb push app/src/main/assets/scripts/tvzenbox-bootstrap.sh /data/local/tvzenbox/tvzenbox-init.sh adb shell chmod 755 /data/local/tvzenbox/tvzenbox-init.sh # ⑥ 安装真机(SlimBox)自启钩子 —— 必须写到裸路径 /data/media/0/init.d/ adb shell mkdir -p /data/media/0/init.d adb push deploy/initd-tvzenbox.sh /data/media/0/init.d/tvzenbox adb shell chmod 755 /data/media/0/init.d/tvzenbox # ⑦(标准 su 盒子的 rc 备用路径)写自启声明 adb shell mount -o rw,remount /system adb push app/src/main/assets/system/tvzenbox.rc /system/etc/init/tvzenbox.rc adb shell mount -o ro,remount /system # ⑧ 重启并验证 adb reboot adb shell cat /data/local/tvzenbox/initd.log # 应有 init.d hook fired / guard.sh 已拉起 adb shell cat /sdcard/tvzenbox/data.sh # 应有 BOOT_SEQ / LAST_GUARD_TICK_EPOCH adb shell cat /sdcard/tvzenbox/logs/guard.log # 应有 guard start ``` > `deploy.bat` 已自动完成上面的 ③~⑥,并额外处理 CRLF 归一、config.sh 保留、rc 暂存到 `/sdcard/tvzenbox/system/tvzenbox.rc` 等细节。手动方式仅适合排障。 ### 3.3 本地仓库路径 ↔ adb / 设备路径映射(重要) > 方便你以后自己安装:左边是仓库里的文件,右边是推送到盒子后的目标位置。 | 本地仓库路径(PC) | adb / 设备目标路径 | 说明 | | --- | --- | --- | | `app/build/outputs/apk/debug/app-debug.apk` | `adb install` 安装为包 `com.tvzenbox` | APK 产物 | | `app/src/main/assets/scripts/config.sh` | `/sdcard/tvzenbox/config.sh` | 配置(已存在则不覆盖) | | `app/src/main/assets/scripts/funcs.sh` | `/sdcard/tvzenbox/funcs.sh` | 公共函数、心跳、原子写 | | `app/src/main/assets/scripts/timekeep.sh` | `/sdcard/tvzenbox/timekeep.sh` | 网络探测与时钟可信判定 | | `app/src/main/assets/scripts/guard.sh` | `/sdcard/tvzenbox/guard.sh` | 常驻守护主循环 | | `app/src/main/assets/scripts/init.sh` | `/sdcard/tvzenbox/init.sh` | 开机入口,拉起 guard | | `app/src/main/assets/scripts/tvzenbox-bootstrap.sh` | `/data/local/tvzenbox/tvzenbox-init.sh` | 开机早期引导桥接 | | `deploy/initd-tvzenbox.sh` | `/data/media/0/init.d/tvzenbox` | **真机自启钩子(裸路径 755)** | | `app/src/main/assets/system/tvzenbox.rc` | `/sdcard/tvzenbox/system/tvzenbox.rc`(暂存)→ `/system/etc/init/tvzenbox.rc`(标准盒子) | 自启声明 rc | | `system/etc/init/tvzenbox.rc` | `/system/etc/init/tvzenbox.rc` | 手动安装参考副本 | **关于 `/sdcard`、`/storage/emulated/0`、`/data/media/0` 的关系**: ``` /data/media/0/ ← ext4 裸路径(真实文件系统,root 可写,chmod 生效) /storage/emulated/0/ ← Android 标准外部存储逻辑路径 /sdcard/ ← 兼容别名,一般指向 /storage/emulated/0 ``` - 三者底层指向**同一份数据**。 - `/sdcard` 与 `/storage/emulated/0` 走 **FUSE**,普通 App 可读写,但 FUSE 会映射权限,**chmod 不生效**(实测 chmod 755 后仍显示 664)。 - `/data/media/0` 是 **ext4 裸路径**,`chmod` 生效,需要 root 才能写。 - 本项目自启钩子必须放在 `/data/media/0/init.d/tvzenbox` 并保持 755,因为 ROM 开机执行 `run-parts /data/media/0/init.d`,而 busybox `run-parts` 会跳过不可执行文件。 - App 没有 root,无法写 `/data/media/0/init.d`,所以这步必须由 adb 部署脚本以 root 安装一次。 #### 自启链路与文件类型(重要) ``` 盒子开机 └─ SlimBox ROM 开机执行 run-parts /data/media/0/init.d(目录) └─ /data/media/0/init.d/tvzenbox 【文件:开机触发钩子】 └─ /data/local/tvzenbox/tvzenbox-init.sh 【文件:引导桥接】 └─ /sdcard/tvzenbox/init.sh 【文件:开机正式入口】 └─ nohup /sdcard/tvzenbox/guard.sh 【文件:真守护】 ``` | 设备路径 | 类型 | 仓库源文件 | 角色 | | --- | --- | --- | --- | | `/data/media/0/init.d/` | **目录** | — | ROM 固定扫描的开机脚本目录 | | `/data/media/0/init.d/tvzenbox` | **文件**(脚本) | `deploy/initd-tvzenbox.sh` | 开机触发钩子:等 `/sdcard` 就绪后调用引导桥接 | | `/data/local/tvzenbox/tvzenbox-init.sh` | **文件**(脚本) | `app/src/main/assets/scripts/tvzenbox-bootstrap.sh` | 引导桥接:确认 `/sdcard/tvzenbox/init.sh` 就绪后 exec 它 | | `/sdcard/tvzenbox/init.sh` | **文件**(脚本) | `app/src/main/assets/scripts/init.sh` | 开机正式入口:记录开机锚点、拉起 guard | | `/sdcard/tvzenbox/guard.sh` | **文件**(脚本) | `app/src/main/assets/scripts/guard.sh` | 常驻守护主循环 | 要点: - **`/data/media/0/init.d/tvzenbox` 是文件,不是目录**;`/data/media/0/init.d/` 才是目录。 - 文件名故意去掉 `.sh` 后缀:busybox `run-parts` 默认跳过名字含 `.` 的文件。 - 只放 `tvzenbox-init.sh` 不会自动执行——它需要有人调用;`init.d/tvzenbox` 就是开机时唯一自动调用它的入口。 - 手动安装时这两处都要部署(见 3.2 节 ⑤⑥ 两步),漏掉任何一个都不会自启。 ### 3.4 遥控操作 - 方向键移动焦点;OK 确认;返回关闭浮层/退出。 - 主界面可操作:总开关、设置观看时长、查看运行日志、返回系统、退出界面、关于。 - 关于页可滚动查看配置文件路径与安装/卸载说明。 ### 3.5 构建 APK ```bash # Windows build.bat debug # 或直接 Gradle ./gradlew assembleDebug ``` --- ## 4. 方案 B:脚本自动化部署 `deploy/` 提供 Windows 批处理入口,内部调用 Python 实现;功能一一对应 **部署** 与 **卸载**。 | 脚本 | 平台 | 作用 | | --- | --- | --- | | `deploy/deploy.bat` → `deploy.py` | Windows(CMD) | 构建 APK → 连接 → 安装 → 释放脚本 → 引导链 → rc → init.d 钩子 → 校验 | | `deploy/uninstall.bat` → `uninstall.py` | Windows(CMD) | 停守护 → 删 rc/钩子 → 删工作目录 → 卸 APK → 断开 | ### 4.1 参数与默认值 参数(**IP / 端口 / 用户名 / 密码**)支持环境变量与命令行参数覆盖(命令行 > 环境变量 > 默认值): | 变量 | 含义 | 默认值 | | --- | --- | --- | | `ADB_HOST` | 盒子 IP | `192.168.1.100` | | `ADB_PORT` | adb 端口 | `5555` | | `ADB_USER` | 设备侧用户名(root 提权用) | `root` | | `ADB_PASS` | 设备侧密码(**无密码留空**) | 空 | | `ADB_BIN` | adb 可执行文件 | `adb` | | `ADB_SERIAL` | 直接指定序列号(给了就跳过 `connect`) | 空 | | `JAVA_HOME` / `ANDROID_HOME` | 构建用(仅部署脚本) | 本机 JDK17 / SDK 路径 | > **关于「用户名 / 密码」**:adb 本身不需要账号密码;`ADB_USER` / `ADB_PASS` 用于设备侧 **root 提权**。本项目真机为 adb root,部署脚本会先探测 `adb shell id -u`,若是 `root` 就直接用 `adb shell`,不经过 `su`;带 `su` 的盒子会自动回退到 `su <用户> -c '<命令>'`,若 `su` 需要密码,脚本会尝试把密码喂给标准输入(尽力而为,不保证所有 ROM)。 ### 4.2 用法示例 ```bat REM —— Windows CMD —— deploy\deploy.bat deploy\deploy.bat -H 192.168.1.123 -u root deploy\deploy.bat --ask deploy\deploy.bat --dry-run --skip-build deploy\deploy.bat -H 192.168.1.123 --restart REM 部署后重启盒子验证自启 ``` ```bat REM —— 卸载 —— deploy\uninstall.bat -H 192.168.1.123 --yes deploy\uninstall.bat -H 192.168.1.123 --keep-data --yes deploy\uninstall.bat -H 192.168.1.123 --dry-run --yes ``` > 不带 `--yes` 时,卸载会交互确认;非交互环境必须显式加 `--yes`。 > Windows 批处理版为 **GBK 编码**(中文 Windows 下双击/CMD 运行可直接显示中文)。用 VS Code 查看时请把编码切到 GBK。实际部署流程统一由 `.py` 实现,避免批处理引号/转义复杂性。 ### 4.3 部署脚本做的事(8 步) | 步骤 | 动作 | 说明 | | --- | --- | --- | | 1/8 | 环境自检 | 检查 `adb`、定位工程根、确认脚本/rc 源 | | 2/8 | 构建 APK | `gradlew assembleDebug`;`--skip-build` 可跳过 | | 3/8 | 连接设备 | `adb connect IP:端口` + `wait-for-device` | | 4/8 | 安装 APK | `adb install -r -g`(覆盖安装并预授存储权限) | | 5/8 | 释放守护脚本 | CRLF 归一后 push 到 `/sdcard/tvzenbox/`;**`config.sh` 已存在则跳过** | | 6/8 | 部署引导桥接 | `/data/local/tvzenbox/tvzenbox-init.sh`(755) | | 7/8 | 安装 rc | remount rw → 写 `/system/etc/init/tvzenbox.rc` → 还原 ro(标准盒子用) | | 7.5/8 | 安装 ROM init.d 钩子 | 写 `/data/media/0/init.d/tvzenbox`(755);**真机可靠自启路径** | | 8/8 | 结果校验 | 列脚本 / cat rc / 查钩子与引导脚本 / 查包状态 | --- ## 5. `config.sh` 配置字段 设备侧配置文件:`/sdcard/tvzenbox/config.sh`。APK 首次启动时若不存在会创建默认值;**已存在则永不覆盖**(保留用户设置)。 | 字段 | 默认值 | 含义 | | --- | --- | --- | | `ENABLED` | `1` | 总开关:`1` 开启 / `0` 关闭。关闭后守护不判罚、不关机。App 主界面可切换,长期生效。 | | `WATCH_MINUTES` | `45` | 观看时长(分钟)。开机满该时长后自动关机(R1)。App 设置界面可改。 | | `FAST_WINDOW_SECONDS` | `600` | 快速重启惩罚窗口(秒)。上次自动关机后 10 分钟内再次开机判为作弊(R2)。UI 不可改。 | | `TICK_SECONDS` | `60` | 守护轮询间隔(秒)。 | | `PING_TARGETS` | `"223.5.5.5 114.114.114.114"` | 网络探测目标,空格分隔。任一可达即视为有网。 | | `TRUST_STALE_SECONDS` | `600` | UI 判断「时钟可信是否陈旧」的显示阈值(秒),与 R2 窗口无关。 | | `LOG_MAX_BYTES` | `1048576` | 日志轮转上限(字节,1 MB)。超过后保留尾部 200 行。 | | `SHOW_MAIN_SWITCH` | `1` | 主界面是否显示总功能开关。`0` 隐藏。 | 写死常量(不写入配置):`BOOT_SETTLE_SECONDS=60`(开机静置/防作弊判定前的 60 秒窗口)。 --- ## 6. 项目大致流程 ``` 盒子开机 └─ SlimBox ROM:sys.boot_completed / dev.bootcomplete → slim_box_scripts └─ run-parts /data/media/0/init.d └─ /data/media/0/init.d/tvzenbox(等 /sdcard 就绪) └─ /data/local/tvzenbox/tvzenbox-init.sh(引导桥接) └─ exec /sdcard/tvzenbox/init.sh ├─ CRLF 自愈 ├─ 选定可写工作目录(/sdcard → /storage/emulated/0 → /data/local/tvzenbox) ├─ 记录 BOOT_SEQ / LAST_BOOT_WALL / LAST_BOOT_UPTIME └─ nohup 拉起 guard.sh └─ 常驻主循环: ├─ 单实例锁(guard.pid) ├─ 写守护心跳(LAST_GUARD_TICK_EPOCH) ├─ 开机静置 60 秒 ├─ 每 TICK_SECONDS(60) tick: │ ├─ 读 config.sh │ ├─ ENABLED=0?→ 空转 │ ├─ 安全阀 FAIL_COUNT≥2?→ 空转 │ ├─ 时间可信?→ 判 R2 作弊(命中即关机 fast_reboot) │ ├─ 到点?→ R1 定时关机(auto_timer) │ └─ poweroff:写 data.sh → sync → reboot -p ``` > 标准 `su` 盒子(支持解析运行期新增 rc)可改走 `/system/etc/init/tvzenbox.rc` → `/data/local/tvzenbox/tvzenbox-init.sh` 同一引导链。本项目真机实测 SlimBox ROM **不解析运行期新增的 rc**,因此必须依赖上面的 init.d 钩子。 各脚本职责: | 脚本 | 位置 | 职责 | | --- | --- | --- | | `tvzenbox.rc` | `/system/etc/init/` | init 自启声明(标准盒子备用路径) | | `tvzenbox-init.sh` | `/data/local/tvzenbox/` | 开机早期引导桥接,等 `/sdcard` 就绪 | | `init.sh` | `/sdcard/tvzenbox/` | 正式入口:选目录、记开机锚点、拉起守护 | | `guard.sh` | `/sdcard/tvzenbox/` | 常驻守护:R1 / R2 / 总开关 / 安全阀 / 心跳 | | `funcs.sh` | `/sdcard/tvzenbox/` | 公共函数:日志、原子写、时间、poweroff、心跳 | | `timekeep.sh` | `/sdcard/tvzenbox/` | 网络探测与时钟可信判定 | | `config.sh` | `/sdcard/tvzenbox/` | 用户配置(§5) | | `data.sh` | `/sdcard/tvzenbox/` | 状态:上次自动关机时间/原因、可信时间戳、心跳、开机序号、失败计数 | --- ## 7. 卸载 > APK 卸载不会删除 `/sdcard/tvzenbox/`、`/system/etc/init/tvzenbox.rc`、`/data/local/tvzenbox/`、`/data/media/0/init.d/tvzenbox`。要彻底移除守护与自启,必须同时清理这些路径。 ### 7.1 一键卸载 ```bat deploy\uninstall.bat -H 192.168.1.123 --yes ``` ### 7.2 手动卸载 ```bash # ① 结束常驻守护(尽力而为;无 su 盒子用 adb root) adb shell pkill -f guard.sh # ② 删除 ROM init.d 自启钩子 adb shell rm -f /data/media/0/init.d/tvzenbox # ③ 删除 rc 自启声明(挂载可写 → 删 → 还原只读) adb shell mount -o rw,remount /system adb shell rm -f /system/etc/init/tvzenbox.rc adb shell mount -o ro,remount /system # ④ 删除工作目录与引导目录(配置 + 状态 + 日志) adb shell rm -rf /sdcard/tvzenbox adb shell rm -rf /data/local/tvzenbox # ⑤ 卸载 APK adb uninstall com.tvzenbox # ⑥ 断开 adb disconnect 192.168.1.123:5555 ``` > 无 `su` 的盒子应使用可提权到 root 的 adb(`adb root` 或受权 shell)执行上述删除;标准 `su` 盒子可把 `adb shell` 换成 `adb shell su -c '...'`。推荐直接用 `deploy\uninstall.bat --yes` 自动处理 root 探测。 ### 7.3 脚本自动化卸载 ```bat REM Windows CMD deploy\uninstall.bat --yes deploy\uninstall.bat --keep-data --yes deploy\uninstall.bat --dry-run --yes ``` 不带 `--yes` 时,交互终端会要求输入 `y` 确认;非交互环境必须显式加 `--yes`。 --- ## 8. 常用选项速查 | 选项 | 部署 | 卸载 | 说明 | | --- | :-: | :-: | --- | | `-H, --host ` | ✓ | ✓ | adb IP | | `-p, --port ` | ✓ | ✓ | adb 端口 | | `-u, --user ` | ✓ | ✓ | 设备侧用户名(root 提权) | | `-P, --pass ` | ✓ | ✓ | 设备侧密码(无则留空) | | `-s, --serial ` | ✓ | ✓ | 直接指定 adb 序列号 | | `-A, --apk ` | ✓ | | 指定 APK 路径 | | `--skip-build` | ✓ | | 不构建,用已有 APK | | `--ask` | ✓ | | 交互式询问四项参数 | | `--restart` | ✓ | | 部署后重启盒子以验证自启 | | `--keep-data` | | ✓ | 保留 `/sdcard/tvzenbox` | | `--yes` | | ✓ | 非交互直接确认 | | `--dry-run` | ✓ | ✓ | 只打印命令,不执行 | | `-h, --help` | ✓ | ✓ | 显示帮助 | --- ## 9. 常见问题与降级 | 现象 | 原因 | 处理 | | --- | --- | --- | | `adb connect` 失败 | 无线调试未开 / IP 端口错 | 盒子设置里开启无线调试;或改用 USB(`-s <序列号>`) | | 盒子不自启 / `initd.log` 没有 hook | ROM init.d 钩子未安装,或 `/sdcard` 被清空 | 重跑 `deploy\deploy.bat -H `;确认 `/data/media/0/init.d/tvzenbox` 是 755 且写到裸路径 | | 写了 rc 仍不自启 | 本项目真机 ROM 不解析运行期新增 rc | 依赖 `/data/media/0/init.d/tvzenbox`;rc 只作标准 su 盒子备用,或改走 Magisk 模块 | | 界面「守护进程存活」显示 `×` | 守护未运行,或心跳过期 | 查 `initd.log` / `guard.log` / `data.sh` 的 `LAST_GUARD_TICK_EPOCH`;重启盒子或重新部署 | | 脚本运行报 `: not found` | 脚本带 CRLF | 部署脚本已做 CRLF 归一;手动部署请用 `tr -d '\r'` 后 push | | 不按设定时间关机 | 时长被改 / 守护未跑 / 开机静置与 tick 延迟 | 查 `config.sh` 的 `WATCH_MINUTES` 与 `ENABLED`;最多延迟约一个 `TICK_SECONDS` | | `ping` 判成离线 | 部分 ROM 的 `ping` 不支持 `-W` 参数 | 失败安全(判离线→跳过防作弊);真机确认后调整 | | 中文在 CMD 里乱码 | 批处理为 GBK 编码 | 用中文 Windows 默认控制台运行;或在编辑器里切 GBK 查看 | --- ## 10. 验证清单(真机) 盒子到货后按 `TvZenBox-TASKS.md` §4「人工 / 真机任务」逐条跑,并把「操作 / 期望现象 / 实际现象 / 结论」记录到 `docs/manual-test.md`。三条关键项: 1. **R1**:开机满设定时长(默认 45 分钟)自动关机。 2. **R2**:自动关机后 10 分钟内再开机,约 60 秒内再次关机。 3. **断网不「开机即关」**:断网后开机,只按开机时长兜底,不会立刻关机。 --- ## 11. 附:设备侧路径清单 | 路径 | 谁创建 | 说明 | | --- | --- | --- | | `/sdcard/tvzenbox/` | APK / 部署脚本 | 工作目录 | | `/sdcard/tvzenbox/{config,funcs,timekeep,guard,init}.sh` | 同上 | 守护脚本 | | `/sdcard/tvzenbox/config.sh` | 同上 | 配置(含 `ENABLED` / `WATCH_MINUTES` / `SHOW_MAIN_SWITCH`) | | `/sdcard/tvzenbox/data.sh` | `init.sh` / `guard.sh` | 状态(原子写,含 `LAST_GUARD_TICK_EPOCH` 心跳) | | `/sdcard/tvzenbox/logs/{init,guard,selfcheck}.log` | 各脚本 | 日志(`guard.log` 超 1 MB 自动轮转) | | `/sdcard/tvzenbox/run/guard.pid` | `guard.sh` | 单实例锁 | | `/sdcard/tvzenbox/system/tvzenbox.rc` | 部署脚本 / APK | rc 暂存副本(与 App 的 `RC_COPY` 对齐) | | `/data/local/tvzenbox/tvzenbox-init.sh` | 部署脚本 / APK | 开机早期引导桥接 | | `/data/local/tvzenbox/initd.log` | init.d 钩子 | 钩子执行日志 | | `/data/media/0/init.d/tvzenbox` | 部署脚本 | **真机(SlimBox)自启钩子(裸路径 755)** | | `/system/etc/init/tvzenbox.rc` | APK / 部署脚本 | 自启声明(标准 su 盒子备用路径) | > `deploy\uninstall.bat --yes` 会清理上表全部路径;APK 卸载后其应用私有目录由系统回收。