# 息屏自动唤醒亮屏方案讨论 > 背景:Pixel 10 Pro Fold (Android 15) 息屏状态下微信消息发送失败 > 核心问题:息屏是否必然导致发送失败?能否通过"自动亮屏"绕过限制? > 时间:2026-05-23 --- ## 一、为什么息屏会导致发送失败?(Android 15 限制分析) ### 1.1 息屏 ≠ 只是屏幕变黑 Android 15 在息屏时会同时激活多层限制: ``` 用户按下电源键 / 超时息屏 │ ├──→ Display OFF(屏幕关闭) │ ├──→ Keyguard ON(锁屏界面激活,若有密码需解锁) │ ├──→ Doze Mode(浅睡眠,限制网络/闹钟/JobScheduler) │ └── 进入 doze 后:网络批量处理、闹钟延迟、wakelock 忽略 │ ├──→ App Standby(应用待机桶,限制后台活动) │ └── 微信可能被分到 RARE/RESTRICTED 桶 │ └──→ Background Activity Launch 限制 └── 后台应用(包括通过 su 启动的)禁止启动 Activity ``` ### 1.2 我们遇到的限制层级 | 层级 | 当前是否受影响 | 说明 | |------|-------------|------| | 屏幕关闭 | ✅ 是 | `am start` 不执行,需要 `input keyevent 26` 点亮 | | 锁屏界面 | ⚠️ 未知 | Pixel 是否有密码/指纹?亮屏后是否卡在 Keyguard? | | Doze 模式 | ⚠️ 可能 | 即使亮屏,Doze 可能仍在运行,限制网络调度 | | 后台启动限制 | ⚠️ 可能 | Termux 通过 `su` 执行命令,但微信进程本身不是前台 | | NetScene 队列冻结 | ⚠️ 可能 | 微信内部可能在息屏时暂停消息发送队列 | **关键结论**:即使屏幕亮了,如果 Doze 仍在运行、或微信 NetSceneDispatcher 未恢复,发送仍可能失败。 --- ## 二、自动唤醒亮屏的技术方案(6 种) ### 方案 A:模拟电源键点亮(已部分实现) **做法**: ```bash input keyevent 26 # 模拟电源键,Toggle 屏幕开关 ``` **限制**: - 只点亮屏幕,**不解锁**锁屏界面 - 如果手机有 PIN/密码/指纹,会卡在 Keyguard - Doze 模式**不会退出**(需要传感器运动或插拔充电) **适用条件**:手机无密码(Swipe only)或 Smart Lock 已信任当前位置/设备 **可行性**:⭐⭐⭐ 部分可行 --- ### 方案 B:模拟滑动手势解锁 **做法**: ```bash # 先点亮 input keyevent 26 sleep 300ms # 模拟从底部向上滑解锁(无密码时) input swipe 500 1200 500 500 300 ``` **限制**: - 仅适用于**无密码**的 Swipe 解锁 - 有 PIN/密码/图案/指纹时完全无效 - 不同手机分辨率不同,滑动坐标需适配 **适用条件**:手机未设置任何安全锁屏 **可行性**:⭐⭐ 受限极大 --- ### 方案 C:发送高优先级通知唤醒 **原理**:Android 允许某些通知唤醒屏幕(如来电、闹钟) **做法**: ```bash # 通过 termux-notification 发送一个 IMPORTANCE_HIGH 通知 # 并设置唤醒屏幕标志 ``` **限制**: - 需要 `termux-api` 应用及后台服务运行 - Android 15 对通知唤醒屏幕有严格限制,通常只有电话/闹钟应用可以做到 - 用户需在设置中允许 Termux "唤醒屏幕" **适用条件**:用户手动授权 + Termux API 常驻 **可行性**:⭐⭐ 不可靠 --- ### 方案 D:通过 AlarmManager / 精确闹钟触发 **原理**:设置一个精确闹钟,闹钟触发时系统会短暂退出 Doze,允许应用执行操作 **做法**: ```bash # 通过 termux 的脚本或 Android 应用设置 AlarmManager # 触发时执行发送逻辑 ``` **限制**: - 闹钟只能唤醒**自己的应用**,不能直接唤醒微信 - 闹钟触发时屏幕不一定亮 - Android 15 需要 `SCHEDULE_EXACT_ALARM` 权限 **适用条件**:仅适用于定时任务,不适用于实时消息回复 **可行性**:⭐ 不适合实时回复场景 --- ### 方案 E:保持屏幕常亮( prevention 而非 cure ) **原理**:不让手机息屏,从根本上避免问题 **做法**: ```bash # 方法 1:修改系统设置(需要 root) su -c "settings put system screen_off_timeout 2147483647" # 方法 2:使用 WakeLock(需要应用支持) # Termux 中运行 termux-wake-lock(但这只保持 CPU,不关屏幕) # 方法 3:充电时保持亮屏(设置中 Developer Options) ``` **限制**: - 耗电严重 - OLED 屏幕可能烧屏 - 用户接受度低 - 如果手机在口袋里,误触问题 **适用条件**:设备长期插电使用,且用户接受屏幕常亮 **可行性**:⭐⭐⭐ 技术可行,但体验差 --- ### 方案 F:利用 Smart Lock / 信任设备自动解锁 **原理**:Android Smart Lock 可以在特定条件下(如连接到信任的蓝牙设备、位于信任的地理位置)自动跳过锁屏。 **做法**: 1. 用户在手机设置中开启 Smart Lock 2. 添加信任条件(如连接到家里 Wi-Fi、信任的蓝牙手表/耳机) 3. 当条件满足时,`input keyevent 26` 点亮屏幕后自动解锁 **限制**: - 需要用户手动配置 - 安全性降低 - 如果条件不满足,仍然卡在锁屏 **适用条件**:用户愿意配置 Smart Lock,且有稳定的信任条件 **可行性**:⭐⭐⭐ 依赖用户配置 --- ## 三、更深层的分析:亮屏后发送就一定成功吗? ### 3.1 当前 Frida 测试结果告诉我们什么? 我们在**亮屏状态**下调用 `u01.m1.a()`,返回 `true`,但 DB 中**没有新消息**。 这说明: 1. **调用链可能本身就是错的** — `m1.a()` 不是真正发送消息的方法 2. **或者**,微信内部需要额外的初始化步骤 **关键推论**:即使我们通过某种方式让屏幕亮了,如果调用链不正确,发送仍然失败。 ### 3.2 需要先解决"亮屏发送",再解决"息屏唤醒" 当前问题的优先级应该是: ``` P0: 亮屏 + 微信前台 → 能否成功发送?(Frida 测试 q1.b() / d()) │ ├──→ 如果亮屏也失败:调用链有问题,与息屏无关 │ └──→ 如果亮屏成功:再解决息屏限制 │ ├──→ 方案 A/B/F:自动亮屏+解锁 └──→ 方案 E:保持常亮 ``` --- ## 四、综合方案推荐 ### 方案 1:双路径发送(推荐) ``` 消息检测(sqlcipher 轮询 / 通知监听) │ ├──→ 检测到微信在前台 ──→ 直接调用发送 API │ └──→ 检测到息屏 ────────→ input keyevent 26 唤醒 │ ├──→ 无密码 / Smart Lock ──→ 自动解锁 │ └──→ 微信前台 → 发送 │ └──→ 有密码且未 Smart Lock ──→ 发送失败,记录待发送队列 │ └──→ 下次用户解锁时批量发送 ``` **优点**: - 前台时实时发送 - 息屏时尝试唤醒,成功则发,失败则缓存 - 不丢失消息 **缺点**: - 息屏时回复有延迟(需等用户下次解锁) - 需要维护待发送队列 --- ### 方案 2:保持微信前台常驻(激进方案) ```bash # 1. 设置屏幕常亮(root) su -c "settings put system screen_off_timeout 2147483647" # 2. 微信保持在 LauncherUI 前台 # 3. 使用 termux-wake-lock 防止 CPU 休眠 ``` **配合硬件**: - 手机长期连接充电器 - 降低屏幕亮度到最低 - 使用 OLED 黑色主题减少烧屏 **优点**: - 完全绕过息屏限制 - 发送实时性最好 **缺点**: - 耗电 - 烧屏风险 - 用户体验差(手机一直亮着) --- ### 方案 3:Termux 前台服务 + 通知监听(折中方案) **原理**: 1. Termux 运行在**前台服务**模式(显示一个常驻通知) 2. 前台服务不受 Doze 限制,可以持续运行 3. 收到微信通知时,通过 `input keyevent 26` 唤醒屏幕 4. 如果手机无密码/Smart Lock,微信启动后自动前台 5. 发送消息 **关键条件**: - Termux 需要在前台服务模式下运行 - 手机不能有密码锁,或已配置 Smart Lock --- ## 五、针对 Pixel 10 Pro Fold 的具体建议 ### 5.1 先确认锁屏状态 ```bash # 检查当前 Keyguard 状态 adb shell dumpsys window | grep -i "keyguard" # 或 adb shell dumpsys deviceidle | grep -i "screen" ``` **输出分析**: - `mDreamingLockscreen=true` → 有锁屏界面 - `mInputRestricted=true` → 需要解锁才能操作 ### 5.2 如果手机有密码 **路径 1**:建议用户开启 Smart Lock - 设置 → 安全 → Smart Lock → 信任的地点/设备 - 添加家里位置或连接的蓝牙耳机 **路径 2**:使用 ADB + 电脑保持连接 - 电脑端运行 `adb shell svc power stayon usb` - 手机连接电脑时屏幕常亮 - 但这要求电脑一直在旁边 **路径 3**:接受延迟回复 - 息屏时缓存回复到队列 - 用户下次解锁手机时自动发送队列中的消息 ### 5.3 如果手机无密码 直接实现方案 A + B: ```javascript async function wakeAndUnlock() { await shell('input keyevent 26', 3000); // 点亮 await sleep(500); await shell('input swipe 500 1200 500 500 300', 3000); // 上滑解锁 await sleep(300); await shell('am start -n com.tencent.mm/.ui.LauncherUI', 5000); // 启动微信 } ``` --- ## 六、结论与下一步 ### 核心结论 1. **息屏限制是真实存在的**:Android 15 的 Doze + 后台启动限制确实会阻止消息发送 2. **但当前更大的问题是调用链**:亮屏状态下 `u01.m1.a()` 也不工作,说明不是单纯的息屏问题 3. **自动亮屏技术上可行**:`input keyevent 26` 已验证可用,但**解锁**是瓶颈 4. **优先级应该是**: - **P0**:用 Frida 测试 `q1.b()` 和 `q1.d()`,找到真正发送方法 - **P1**:确认亮屏+前台状态下能否稳定发送 - **P2**:解决息屏唤醒(根据用户锁屏配置选择方案 A/B/F/E) ### 建议用户决策 | 你的手机状态 | 推荐方案 | 实施难度 | |-----------|---------|---------| | 无密码 / Swipe only | 方案 A + B:唤醒 + 滑动解锁 | 低 | | 有密码,可开 Smart Lock | 方案 F:Smart Lock 自动解锁 | 中(需配置) | | 有密码,不能开 Smart Lock | 方案 1(双路径):前台实时发,息屏缓存延迟发 | 中 | | 长期插电放在桌上 | 方案 E:屏幕常亮 | 低(但耗电) | --- ## 七、待确认问题(需要用户回答) 1. **你的 Pixel 10 Fold 有设置锁屏密码/PIN/指纹吗?** - 如果有,能否开启 Smart Lock? 2. **手机通常是放在桌上插电,还是随身携带?** - 这影响"屏幕常亮"方案的可行性 3. **对回复延迟的容忍度如何?** - 是否接受息屏时延迟到下次解锁才发送? 4. **是否愿意安装 Termux:API 并保持其前台服务运行?** - 这可以绕过部分后台限制 根据你的回答,我可以给出最精准的实施方案。