为什么设了 30 分钟限额,安卓没在第 30 分钟那一秒挡住
你设了 30 分钟。等你拿起手机,屏幕上显示 33 分钟,阻断页刚刚才弹出来。没崩溃,看不出哪里坏了。它只是晚了。
你如果搜过这个问题,大概翻到的都是教你怎么设限额的文章,几乎没有一篇解释:你已经设好的限额,为什么没卡在那一分钟上。这篇讲的是后者。我自己在做一个安卓屏幕时间 App,所以下面的数字大多来自我自己项目的日志,而且每个数字我都标了它是在哪台设备上测到的。
先把话说在前面,免得这篇读起来像变相推销: 这是安卓给任何第三方 App 的接口层面的限制,我的 App 一样有。各家 App 之间不同的是偏差有多大、往哪个方向偏,不是有没有偏差。
三十秒版本
- 安卓不会主动告诉第三方 App”屏幕上换 App 了”。 没有回调,没有通知。App 只能反复地问。第一批秒数就丢在这里。
- 我的 App 每秒问一次。 即便如此,在一台华为手机上实测,从孩子打开被监控的 App 到我的 App 察觉,中间是 5 到 28 秒。
- 更大的延迟不在检测,而在手机把计时器冻住了。 厂商的省电管理会挂起后台 App。被挂起期间,屏幕时间 App 既不能计时,也弹不出东西。
- 就在这台华为手机上,系统把我 60 秒一次的唤醒闹钟扣了五分钟多 —— 手机自己的闹钟记录里写着最大延迟 5m1s,结果是超过限额之后连续 5 分 33 秒的视频没有被打断。把这个唤醒换成安卓承诺永不延迟的那一类闹钟之后,同一个复现路径变成 57 秒。
- 偏差通常表现为延迟。 这是刻意的设计取向,也有代价:孩子偶尔多用几秒。我们宁可这样,也不愿在时间没到的时候切断。
- 如果超了几十分钟、而且一次提醒都没出现,那不是偏差 —— 那是监控被冻住了,有些手机上有一个具体的设置能修好它。
怎么区分”正常偏差”和”真的坏了”
这条界线比大多数人猜的要靠后。
正常范围(安卓上任何第三方 App 都一样):
- 超过限额之后几秒到一两分钟,阻断才出现
- 计数比你拿秒表量出来的略少
- 有的日子挡得快、有的慢,取决于手机当时在忙什么
不正常,值得查:
- 超了几十分钟,一次提醒都没有。 我的 App 在 60%、75%、90% 的那三次轻提醒同时也是”哨兵”:一次都没响,说明监控根本没在跑。这不是晚,是没在跑。
- 你眼看着孩子在用手机,计数却不动。 那是服务被冻住或者停了,不是偏差。
- 只有在你打开家长 App 之后,提醒才冒出来。 这就是下面那张时间线里的”手动解冻”特征,是服务被冻最清楚的单一症状。
- 计数比真实用量还多。 按我的 App 的设计这不该发生;真发生了那是 bug,不是平台限制。
如果你落在第二组里,先去查厂商自己的后台管理开关(下面「家长能做的事」一节),再下”这个 App 坏了”的结论。
安卓不会告诉 App 屏幕上是什么
这是后面所有问题的根,而且大多数人会意外。
一个普通的安卓 App,没有办法被告知孩子刚才切到了视频 App。早年那些能让一个 App 查看别的 App 在跑什么的接口 —— getRunningTasks、getRunningAppProcesses —— 多年前就因为隐私原因被限制了,现在只会返回调用方自己的那一份。剩下的是 UsageStatsManager,它的方向是反过来的:系统记录用量事件,家长管控 App 去要一段时间窗口内的事件,再读回来发生了什么。这是查询,不是订阅,没有任何东西会推给你。
所以安卓上每一个第三方屏幕时间 App,本质都是一个循环:问、等、再问。而循环有两笔开销 —— 你多久问一次,以及系统的记录多快能反映真实情况。
有一个例外,我摆出来而不是藏起来。无障碍服务确实能更接近实时地观察窗口变化,而谷歌的 Play 政策对”把无障碍接口用在帮助残障用户之外的用途”提出了声明和显著告知的要求。我的项目把无障碍服务移除了,并且定了一条永不重新引入的规矩,所以下面讲的全是”轮询”这个世界里的事。
轮询到底要付多少代价
我的 App 实际是这么跑的,数字是从源码里读出来的,不是约整数:
| 做什么 | 间隔 |
|---|---|
| 检查前台是哪个 App | 1 秒 |
| 从数据库重读家长的设置 | 30 秒 |
| 后台唤醒,即循环被挂起时的安全网 | 60 秒 |
| 把计数写入磁盘 | 每 5 次检查 |
一秒一次的循环听着很精确,但它不是真正的瓶颈。在那台华为手机上,从孩子真正打开被监控 App 到我的 App 记上这一笔,实测是 5 到 28 秒,而且是循环正常运转的时候。这是系统自己的事件记录在追赶,不是循环慢。
当我的 App 自己在前台时,精度是一两秒。但没人关心那种情况。真正要紧的是孩子在视频 App 里 —— 而那恰恰是手机最有动力把我的 App 弄睡着的时候。
真正的元凶:手机把计时器冻住
那些拿续航当卖点的厂商,对后台 App 非常强硬。不一定是杀掉,而是冻住:进程还在列表里,但不再分到 CPU 时间。前台服务不能豁免你,WakeLock 也不能。而且没有任何公开接口可以退出这套机制。
这不是使坏:一台允许任何 App 整天跑一秒一次循环的手机,续航一定难看,而续航是用户会拿出来比的东西。冻结后台是个合理的默认值,只不过对”有正当理由持续计时”的这一小类 App 来说非常致命。
被冻住的时候,屏幕时间 App 不在计时,不在检查,也弹不出任何东西。孩子在看。App 在旁边睡着。
我对此的解法是那个 60 秒唤醒:哪怕循环被冻住,闹钟每分钟响一次,把 App 叫醒,算出漏掉了多少时间,超了就挡。最坏晚一分钟。
设计是这样。下面是它没兜住的那一晚。
一台华为手机上的一次实测
2026 年 6 月 12 日,限额早就超了,打开视频 App 却什么都没发生。切到我的 App 再切回去,立刻就挡住了。典型的进程被冻,但那张 60 秒的网本该兜住它。它没兜住,而手机自己的诊断信息说出了原因。
| 时刻 | 发生了什么 |
|---|---|
| 21:49:53 | 打开视频 App,进程在几秒前被冻。46 秒,无阻断。 |
| 21:50:36 | 我打开自己的 App —— 相当于手动解冻。 |
| 21:50:39 | 再开视频 App。0.7 秒弹出阻断。阻断逻辑一直是好的。 |
| 21:50:43 – 21:56:16 | 视频 App 持续在前台。连续五个 60 秒唤醒闹钟,一个都没投递。 |
| 21:56:16 | 闹钟终于响了,阻断页弹出。 |
也就是超过限额之后连续 5 分 33 秒的视频没被打断 —— 而手机自己认了:系统的闹钟记录里,这个闹钟条目上写着最大延迟 +5m1s。没有取消,也没有排错时间;五个闹钟被整体扣住了,相位还是连着的。
所以问题不是”App 忘了挡”,而是”App 压根没被叫醒去发现该挡了”。
修法是什么,代价是什么
安卓的闹钟不止一类。最强的一类是留给闹铃的,系统承诺即使在低功耗状态也按时投递 —— 因为厂商要是敢延迟这一类,用户就会睡过头误事。
我把那个唤醒挪进了这一类,但只在孩子确实处于被阻断状态、并且屏幕亮着的时候。在同一台手机上,同样的复现路径从 5 分 33 秒变成 57 秒。
代价是看得见的,我宁可自己说清楚,也不想让家长自己发现:孩子被阻断且屏幕亮着的这段时间,状态栏会出现一个闹钟图标。解锁或者跨天之后,大约一分钟内消失。
以上全部是在一台运行 EMUI 的华为手机上测到的。 不是所有华为手机,更不是所有安卓手机 —— Pixel 不会这么激进地冻结后台,同样的测试在 Pixel 上复现不出来。我能说的是:在那台设备上,延迟是真的,原因来自系统自己的日志,改动堵掉了其中大部分。
为什么偏差会往”晚”的方向走
这是我作为家长最想知道的一段,也是唯一一处答案不是”安卓的问题”而是”我选的”。
我的 App 有三个地方,宁可把时间丢掉,也不去估:
一、间隔过长时截断,而不是外推。 循环预期两次检查之间是一秒;手机在节流的时候可能是四十秒。如果孩子明显一直在同一个 App 里,最多计入 60 秒。如果这段空隙里 App 换过 —— 也就是中间发生了什么没人知道 —— 最多只计 5 秒。超出上限的部分直接丢弃,不予计入。
二、可疑的空隙整段丢掉。 如果内部计时器发现一次跳变超过 5 秒,它就把这段当作未知,一点都不加。
三、天花板是系统自己的数字。 我的 App 会定期拿自己的累计值去比对安卓对同一批 App 给出的当日用量,如果系统的数更大,就把计数抬上去对齐。它只会往上追到那个数,永远不会超过它,也不会往回退。
三条加在一起,在监控正常运行的前提下,计数倾向于少于真实用量。一个偏向少算的账,需要更多真实分钟才能到达限额,所以阻断会落在偏晚的一侧。
这个取舍是实打实的。选了”宁可晚一点”,就等于选了”有时多给”:孩子偶尔会白赚一两分钟,在表现糟糕的手机上偶尔更多。另一条路是对着被冻住的那段空隙猜一个数往上凑 —— 那有时就意味着在时间没到的时候告诉孩子时间到了。一个被提前切断的孩子,委屈是完全成立的,而且他会记住。那是更糟的失败,所以我选了另一种。
一句话版本,而且是写进用户协议里、不是藏起来的:只要监控确实在跑,时刻不保证,但一定会挡是保证的。至于怎么判断它到底有没有在跑,本文后面单列了一节。
家长能做的事
下面没有一条能把偏差压到零。但每一条都能实实在在把它压小。
去看厂商自己的后台管理开关,不只是电池优化。 这两者常常是互相独立的开关,关掉电池优化根本不会碰到另一个。华为上真正管用的是应用启动管理,默认是”自动管理”。我为这个报废过一次演示录像:视频 App 里 22 分钟,没有任何提醒,也没有阻断,而那台手机的电池白名单早就给了。把 App 改成手动管理、三个子开关全打开之后就好了 —— 改完三分钟内,剩余分钟数就正常往下走了。小米上大致对应的是自启动加上省电策略选”无限制”,三星上是把 App 加进”永不休眠的应用”——不过这两家我自己都没实测过。想要各厂商的具体路径,dontkillmyapp.com 是社区维护的参考。
别在最近任务里把家长 App 划掉。 很多系统会把这个动作读成”用户不想要它了”,这个信号比任何省电设置都强。
把限额当预算,不要当秒表。 如果你想让屏幕在 7:30 关掉,就别把限额设成正好卡在 7:30。
让结束是可预期的,别指望阻断页去宣布它。 一个在无法预测的某一秒突然生效的限额,体验比一个你知道要来的提醒差得多。哪些安卓设置真的会提前提醒、哪些其实不会,我另外写过一篇。
我说不了的部分
我没有一柜子测试机 —— 这里所有实测数字都出自同一台手机,小米、OPPO、vivo、三星上我都没有复现过。
我也没法告诉你别家 App 表现如何。大家读的是同一套系统数据、走的是同一个接口,所以物理规律是一样的;但偏差有多大、往哪偏,那是他们该公布的,不是我该替他们猜的。值得注意的是,没有人公布这个数。谷歌自己的 Family Link 帮助页讲了怎么设限额,也写了设备即将被锁定时孩子会收到通知,但对”统计有多准""执行会延迟多久”只字未提。
这份沉默,就是这一页存在的理由。
本文作者是一个做小龟时光的家长,那是一个面向 6-14 岁孩子的安卓屏幕时间 App:在每日限额的 60%、75%、90% 各安静提醒一次,到 100% 才真正阻断。免费,无广告,无内购。孩子的屏幕时间数据默认留在手机本地——唯一会离开设备的是匿名的崩溃报告和使用统计,这一点我们的隐私政策里也是这么写的。
接着读
- 关于计时,我们想跟你说句老实话 —— 我不越过的那两条线的短版本。
- 怎么让安卓在屏幕时间用完之前提醒孩子 —— 哪些设置会提前提醒,附具体点击路径。
来源与出处
- 各项间隔与上限(1 秒轮询、30 秒设置刷新、60 秒唤醒、60 秒与 5 秒两档空隙上限、5 秒丢弃阈值、取较大值的数据库写入)都是从我自己 App 的源码里直接读出来的常量与逻辑,不是凭记忆写的。
- 5 到 28 秒的检测滞后、+5m1s 的闹钟延迟、5 分 33 秒的裸跑、以及修复后的 57 秒,是 2026-06-12 在一台运行 EMUI 的华为手机上实测的,并与系统用量事件流、事件日志、闹钟 dump 和我的 App 自己的计时记录交叉验证过。
- 22 分钟无提醒那次是同一台手机,2026-07-01,应用启动管理停在默认的”自动”,电池白名单已经给了。
- “Manage your child’s screen time.” Google For Families Help.(2026-08-02 获取,专门查过有没有关于统计精度或执行延迟的说法 —— 没有。)
- UsageStatsManager 安卓接口文档,以及 “Use of the AccessibilityService API” Google Play Console 帮助。两处都是我用自己的话转述的,未做逐字引用。
- dontkillmyapp.com —— 社区维护的各厂商后台限制参考。我没有逐台设备验证过。
未核实: 小米、OPPO、vivo、一加、三星、Pixel 上的同样测量,以及任何其他屏幕时间 App 的精度或执行延迟。