Root 强提醒 3.0:清后台也能接收,静音勿扰下亮屏弹窗

手机静音、通知音量归零、打开严格勿扰,再按灭屏幕,重要消息还能提醒到我吗?这次给自己的 Redmi K60 做了一套「强提醒」:收到服务器消息后,显示普通通知,用内置扬声器播放 1 秒提示音,自动亮屏,再显示一个居中弹窗。

新版已在应用被系统强行停止、没有应用进程的条件下跑通网络接收与提醒,取得了弹窗截图和播放器完成记录。日常接收由手机软件自己完成,电脑只参与开发、安装和验收。本文记录实现方法、安装步骤、后台恢复,以及测试能证明和暂时不能证明的部分。

实测日期:2026-10-17。应用:强提醒 3.0-root-daemon;Magisk 模块:强提醒 Root 独立接收 2.0。本文下载文件不包含设备接收令牌、服务器发布密钥或私有签名密钥。

2026-10-17 完成版:强提醒 3.0-root-daemon 与独立接收模块 2.0 已完成安装和本轮真机验收。接收连接、消息队列和回执由 Magisk 的独立 Root 进程负责。APK 被清后台甚至被系统强行停止后,仍能接收消息;收到消息时才启动应用显示提醒。本文 APK、模块、源码和 SHA-256 均对应这套完成版本。

本轮验收结束状态:应用进程不存在,独立 Root 守护进程仍在线,频道监测正常。已通过开机自启、接收进程退出后恢复、断网重连,以及静音、严格勿扰、息屏条件下的定向网络提醒测试。没有把「常规清后台不影响接收」写成「任何情况下都杀不死」。

1. 最终做成了什么

当前接的是 Telegram 的 @resetnowai 重置频道。服务器采集频道消息,手机用自己的独立接收身份获取消息,然后在本地执行提醒。它不依赖手机里的 Telegram 客户端,也不需要 Shizuku 配对、设备管理员或 Device Owner。

  • 有声音:普通通知用途的音频,持续 1000 毫秒,临时提高本机通知扬声器音量,结束后恢复。
  • 看得见:通知栏保留消息,屏幕自动点亮,显示居中提示,点击「知道了」关闭,或约 15 秒后自动关闭。
  • 可恢复:Magisk 开机服务启动独立接收进程,后台检查负责异常退出后的恢复;用户主动停止后保留停止状态。
  • 可追查:应用能查看权限、网络、频道监测状态和最近接收记录,服务器记录接收与通知回执。

这是给自己授权的 Root 手机做的实验工具。这里的「强」指本机提醒能力增强;手机关机、没有网络、Root 权限失效,仍然会影响送达。换 ROM 后也需要重新验收。

Redmi K60 强提醒实测:屏幕亮起,居中显示重置频道历史回放测试弹窗
真机截图。正文明确标注「测试回放」;这次验收使用定向历史消息,不代表频道刚发生了新的额度重置,也没有向公共频道发送测试消息。

2. APK、Magisk 模块和源码下载

先分清两个安装包:Magisk 模块负责网络接收、持久化队列和进程恢复,APK 负责配置与提醒界面。只有模块、没有 APK 和接收配置,无法使用;只安装 APK 也不会自动获得你的服务器接收资格。

最低系统版本只是安装声明,不代表已经兼容所有 Android 11 以上设备。本文实际验证的组合如下。

项目 实测环境
手机 Redmi K60 / mondrian / arm64
系统 LineageOS 24.0-20261012-NIGHTLY-mondrian,Android 17
Root Magisk 30.7,辅助进程 UID 0
系统状态 SELinux Enforcing;本方案不要求开启 Zygisk

还没安装这套系统的,可以先看 Redmi K60 刷入 LineageOS、Magisk 与 MindTheGapps 的实测记录。强提醒模块与之前的 tz、FRP 模块独立,互不承担对方的功能。

3. 从频道到手机,消息走哪条路

Telegram 公开频道
    ↓ 服务器每 180 秒采集
接收服务:入库、分配递增 seq
    ↓ 独立设备令牌 + HTTPS 长轮询
手机 Root 守护进程:持久化、去重、更新游标
    ↓ 本地固定提醒操作
普通通知 + 1 秒声音 + 亮屏弹窗
    ↓
服务器接收回执 / 通知回执

这里有三个时间,含义完全不同:180 秒是来源采集周期,40 秒是一次长轮询最多等待的时间,1 秒是提示音长度。长轮询等待期间有新消息入库,服务器就可以返回,手机处理后马上续接;它不是每隔 40 秒才检查一次。但频道发布到被服务器采集,仍可能有 0–180 秒以上的延迟。

首次配置使用服务器提供的初始游标,从当前消息位置开始,避免旧消息集中响铃。Root 守护进程以 seq 去重,先持久化再执行提醒。超过 1 小时的积压消息只保存记录;失败回执留在本机重试。收到 HTTP 成功响应、手机提交了提醒、用户真的看到消息,是三件不同的事,不能只凭一个回执就断言用户已经看见。

4. 安装与首次配置

  1. 安装 APK,打开「强提醒」。点击「连接权限与后台保护」,在 Magisk 中只给这个应用授予 Root。授权完成、界面能读取独立接收状态后再继续;不要把所有应用都设为自动允许 Root。
  2. 配置自己的推送服务器。点击同名按钮,填入 HTTPS 服务基础地址、这台手机专用的接收令牌、服务器返回的初始消息游标。修改配置前先停止网络接收。
  3. 安装后台保护模块。Magisk → 模块 → 从本地安装,选择独立接收模块 ZIP,完成后重启。模块本身不携带 APK 或令牌。
  4. 开启接收。回到应用,点击「开启网络接收」,允许通知,检查权限、网络和频道监测状态。成功后 Root 守护进程独立接收,退出应用不影响它。只在消息到来时启动 APK 的提醒组件。
  5. 先本机,后网络。点击「本机测试:1秒声音+亮屏弹窗」确认本地能力;再由自己的服务器发送一条明确标记的定向测试,检查手机表现、最近记录和服务器回执。

当前 APK 适配的是这套自建接收 API,不能直接填 Telegram Bot Token 就使用。给新设备创建独立的读取令牌;本站下载文件也不会赋予对现有私有消息流的访问权。服务器发布权限和 SSH 管理权限都留在服务器侧。

若要接自己的服务,客户端使用下面的最小接口约定。设备令牌放 HTTP 请求头,正常校验证书与域名,不放 URL,也不记录到日志。

GET /events?after=已持久化的最大seq&wait=40
Authorization: Bearer <这台设备的接收令牌>

GET /status
POST /receipt
Content-Type: application/json

{"seq":123,"notified":true,"opened":false}

以上路径都相对于配置的 HTTPS 基础地址;三个设备接口均携带同一设备的鉴权头。消息列表返回 messages,每条至少包含 seq、title、text、created(毫秒时间戳);状态对象提供 source.status、checkedAt、latest、pollSeconds。完整字段处理以下载源码中的 RootPushMain.java 为准,普通 webhook 不能直接替代这个接收协议。

5. 静音与勿扰下,声音为什么能出来

配置界面通过私有标准输入输出管道调用自己的 Magisk 辅助进程。配置完成后,Magisk 模块独立启动 UID 0 的接收守护进程,不依赖应用进程或电脑。控制接口只提供配置、提醒、状态和接收开关等固定操作。服务器传来的标题和正文当作普通文本,不作为 Shell、Intent 或脚本执行。

一次提醒的本地流程是:读取当前音频模式、通知扬声器音量、静音和勿扰状态;确认处于正常音频模式;点亮屏幕并打开本应用弹窗;保存音量恢复记录;临时设置通知扬声器音量;由应用内的 MediaPlayer 播放提示音;最后按条件恢复原状态。

播放用途是 USAGE_NOTIFICATION,通知类别是 CATEGORY_MESSAGE,通知通道自身关闭默认声音,由播放器控制 1 秒音频。实现还使用了系统内部的绕过勿扰、绕过静音音频标志,以及 AudioSystem 的内部音量接口。这些内部行为属于本机实测兼容点,不能当成普通应用的通用公开 API。公开音频用途的定义可参考 Android AudioAttributes 文档。

这台 K60 的通知音量上限是 7 档,程序将 12/15 的提醒强度换算为临时 6/7 档,播放后恢复原值。验收中原生通知扬声器索引为 0 → 6 → 0,全局勿扰始终为 zen_mode=2,铃声模式始终保持静音,通知通道的 canBypassDnd 仍为 false。它不使用闹钟通道或 USAGE_ALARM。

恢复逻辑先确认当前音量和勿扰仍符合本次操作的预期,再回写旧值;检测到独立变化时跳过恢复,避免覆盖用户的新操作。另外有一个独立 Root 子进程,在约 8 秒后检查未完成的恢复记录。独立看护测试中,临时音量 6 成功恢复到原来的 5,并清除了记录。这是异常退出时的补救机制,不能覆盖断电等所有情况。

检测到通话或其他非正常音频模式时,当前版本跳过强声音,保留普通通知。弹窗使用 showWhenLocked 与 turnScreenOn 等本机能力,负责在锁屏表面显示提示,不调用解除安全锁屏的操作。锁屏上会展示正文,因此请只接入适合在锁屏公开显示的消息。

6. 重启和清后台后,怎样恢复接收

接收主体现在是 Magisk 启动的独立 app_process,配置、游标、队列和回执记录保存在 /data/adb/bismih-strong-alert。目录权限 700、配置与队列文件 600。消息先写入本地原子提交的队列,再执行提醒;进程恢复后沿持久化游标继续接收。APK 不运行常驻网络服务。

模块的 service.sh 在系统启动完成后运行,每 5 秒检查自己的接收进程。进程识别同时核对 PID、启动时间与本次启动 ID,避免重启后误认旧进程;接收进程还使用文件锁防止重复实例。模块仅保护自己的两个 Root 进程,实机 oom_score_adj=-900,不改成系统应用,不关闭 SELinux。启动阶段参考 Magisk Boot Scripts 文档。

实测先强行停止 APK,确认应用进程不存在,Root 接收进程继续存活;随后结束 Root 接收进程,模块恢复了它,期间 APK 仍未启动。本次恰好约 0.37 秒观察到新进程,这是碰上了检查时刻,不能理解为固定恢复承诺;常规检查周期为 5 秒,网络恢复还需另计。

异常退出时,服务器可能保留旧长轮询最多 40 秒,临时返回 429。新版按 2 秒间隔等待旧连接释放,先做一次不等待的恢复读取,再进入 40 秒长轮询。消息留在服务器与本地队列里,不依靠一个易丢失的瞬时广播。此次还验证了关闭 Wi-Fi 8 秒、恢复联网后接收定向测试。

网络开启期间,Root 进程续用有超时的 CPU 唤醒锁,因此仍有一个系统层后台进程常驻,也会增加耗电。本次没有测量长时间拔线待机耗电。独立 Root 进程也可以被有 Root 权限的用户结束,系统故障、关闭网络、禁用模块或关机仍会影响接收,不能承诺「永远杀不死」。

模块权限与 APK 授权分开:只撤销 APK 的 Magisk 授权,不会停止已经启用的独立模块。请用应用的停止按钮、Magisk 模块「动作」或禁用/移除模块来停止。用户主动停止会删除接收启用标记,后台检查尊重这个状态。

日常操作时,下面几种「关闭」的含义不同:

操作或状态 独立接收的行为
退出界面、清理最近任务、系统强行停止 APK 不以 APK 进程存活为前提;本轮已验证系统强行停止 APK 后仍能接收并触发提醒
Root 接收进程异常退出 模块按 5 秒检查周期尝试恢复;旧长连接释放与网络重连仍可能带来额外等待
手机重启 保留接收开启状态时,由 Magisk 模块启动;无需先手动打开 APK
应用内「停止网络接收」或模块动作停止 删除接收启用标记并停止进程;后台检查不会替用户重新开启,停止状态跨重启保留
断网或服务器不可达 等待并重连;有网还需要接收服务器可达,无法承诺断网期间实时送达
准备禁用或移除模块 先主动停止接收,再禁用或移除;模块与 APK 分开管理,移除模块不会自动卸载 APK

模块使用 Root 私有目录,APK 的配置界面仍保留设备保护存储中的配置副本。不要把管理员或服务器发布密钥放入设备;需要首次解锁前可用的数据有不同的保护边界,可参考 Android Direct Boot 说明。本次没有在设置安全 PIN 后单独验证首次解锁前的完整提醒链路。

7. 这次到底测到了哪些结果

测试项 实际观察
严格安静条件 静音;铃声、媒体、通知音量均为 0;严格勿扰;屏幕息屏
定向频道历史回放 新版在 APK 强行停止、进程不存在时完成定向回放;播放器报告 1000ms completed、内置扬声器,取得亮屏弹窗截图。此前 2.0 同一提醒链路已由使用者确认声音、亮屏、弹窗
音量与模式恢复 临时通知音量 6/7,结束恢复 0;勿扰保持 2,铃声保持静音;测试结束恢复原测试前设置
手机重启 新版 Root 守护进程开机自动启动,UID 0,不依赖 APK 开机接收服务
结束应用进程 APK 强行停止后 Root 进程继续运行;Root 进程被结束后也已恢复,随后网络测试成功
用户主动停止 新版从 APK 主动停止后观察 12 秒,超过两个检查周期仍未重启,接收唤醒锁释放;从模块动作恢复时 APK 仍未运行
独立音量恢复看护 原值 5、临时 6、看护后回到 5,恢复记录清除
断网重连 Wi-Fi 关闭 8 秒后恢复;本次从定向测试入库到完成提醒约 25.19 秒,包含重连等待,不作为固定延迟承诺
服务端 来源采集状态正常,收到接收与通知回执;未将回执当作用户已读

上述声音测试和截图来自实机。长时间深度休眠、蓝牙/耳机组合、不同厂商 ROM、所有通话场景,以及安全 PIN 首次解锁前接收,仍需分别验证。Root 不等于对这些场景的统一保证。

8. 日常排查与停止方法

  • 本机测试成功,网络消息不来:先看网络状态、令牌和初始游标,再看频道采集状态;权限已就绪不代表服务器已经采到新消息。
  • 401 / 403:设备身份无效,重新在自己的服务器生成接收配置;不要用管理员凭据替代。
  • 429 或重复连接:检查同一令牌是否被两个接收端使用;为设备分配独立身份,等待旧长轮询结束后再试。
  • 只有通知,声音或弹窗缺失:检查 Magisk 授权、应用内提醒结果、音频模式与 ROM 兼容性。Root 失败时保留普通通知,不能据此认定强提醒也成功。
  • 想安静下来:在应用点「停止网络接收」。Magisk 模块的「动作」按钮也能切换接收。主动停止会同步删除保护启用标记,避免后台检查再次拉起。
  • 不玩了:先停止网络接收,在 Magisk 移除后台保护模块并按提示重启,再卸载 APK;若弃用这台接收设备,同时在服务器撤销它的独立令牌。移除模块本身不会卸载应用。

9. 文件校验与自己编译

下载后可用 sha256sum 文件名 校验。当前发布版本的 SHA-256:

strong-alert-root-3.0.apk
bb92bb4e1b236322a8fb53dac3e191a036983ad8931eba969bc429601d78dc3d

strong-alert-root-receiver-2.0.zip
b6c476c5340a8775817f8d8f0fa0eb3e8649a331029f80123950789fd59340c1

strong-alert-root-3.0-source.zip
21afbf0f7af44f9ad93e07c2bc78fa85cb5dc0b3b4699ac92d922cfe0cc3c5b7

源码包中的 app/ 是应用,magisk-module/ 是后台保护模块。准备 JDK、Python 3、Android SDK platform 36 与 build-tools 36.0.0,在 app/ 下执行:

bash build.sh /path/to/android-sdk
cp build/dex/classes.dex ../magisk-module/receiver.dex

再将 magisk-module/ 目录内容打包成 ZIP 供 Magisk 安装,保留目录内的模块文件结构。构建生成自己的签名,无法直接覆盖签名不同的已安装版本;不要为了复用签名发布私有密钥。若要把提醒逻辑整合进另一个应用,应连同组件、权限和生命周期一起移植,并检查辅助进程及模块里的固定包名,不能只复制一次播放调用。整个设计的重点是:消息先可靠落地,提醒在本机执行,有恢复记录,也有用户随时能用的停止开关。

上一篇
下一篇