Skip to content

Releases

v1.0.7

Choose a tag to compare

@zhangdunlong zhangdunlong released this 13 Nov 08:21

v1.0.7 — 重做「冻结系统应用」确认交互

  • 根因:原生「启用」按钮的禁用→启用状态在不同 ROM 主题下渲染不一致,勾选后看不到确认按钮
  • 新交互:移除原生按钮,改为自绘橙底白字「确认启用」按钮——勾选前隐藏,勾选后出现并横跨宽度,取消勾选则隐藏
  • 已在 realme RMX1971 真机验证:勾选后按钮出现、点击 ALLOW_SYSTEM_FREEZE=ON 生效、取消正常关闭

同时包含 v1.0.5/v1.0.6 修复(推荐作用域分号、同意按钮监听器、悬浮球误注入、对话框按钮挤出屏幕)。

v1.0.6

Choose a tag to compare

@zhangdunlong zhangdunlong released this 13 Nov 06:16

v1.0.6 — 修复风险警示对话框按钮被挤出屏幕

  • 根因:正文 ScrollView 未限制高度,大字体缩放/小屏下正文 + 复选框比窗口还高,把底部「取消/启用」按钮顶出可视区,勾选后看不到按钮
  • 修复:正文限高(约屏幕 50%)并滚动;复选框移到滚动区外固定可见;已冻结列表对话框同样限高
  • 已在 realme RMX1971 真机验证:勾选前后按钮均完整可见,勾选后「启用」可点并正常生效

同时包含 v1.0.5 的修复:推荐作用域(xposedscope 分号)、同意按钮监听器、悬浮球误注入。

v1.0.5

Choose a tag to compare

@zhangdunlong zhangdunlong released this 13 Nov 04:19

v1.0.5 — 修复三个问题

修复

  • 推荐作用域不显示:xposedscope 元数据冒号改分号,LSPosed 管理器「推荐作用域」正常解析
  • 「冻结系统应用」同意按钮异常:对话框按钮改用非空监听器,修复「取消/关闭」按钮被禁用、「启用」按钮依赖 getButton 的时序风险
  • 悬浮球误注入:focus 快速路径无条件校验应用信息页内容,修复悬浮球出现在存储/通知/权限等非应用信息页

其他

  • 解冻真机遗留的 com.android.nfc(系统关键包,已在硬白名单内)

已在 realme RMX1971(Android 11 / realme UI / Magisk + Vector)真机复现并验证。

v1.0.4 (104) — 可拖动悬浮球 / Draggable freeze puck

Choose a tag to compare

@zhangdunlong zhangdunlong released this 12 Nov 14:31

settings-app-freezer v1.0.4(发布说明 · 2026-11-12)

本版把页面常驻控件从「底部双药丸栏」重构为 56dp 可拖动悬浮球,并修复了
从列表解冻后主按钮状态不刷新的问题。已在 realme RMX1971(realme UI V11.1 /
Android 11)真机完成全功能验证
,一加 13 全程未触碰。

v1.0.3 引入的「冻结系统应用」(默认关闭 + 三层警示)在本版保持不变,
详见 CHANGELOG.md。


为什么要改 UI

真机实测(1080×2340)发现:旧底栏固定在手势条上方 150dp,
冻结药丸的 bounds [145,1769]-[550,1890] 与应用信息页「应用权限」行
[72,1823]-[264,1888] 完全重叠——该入口被压住、无法点击。
悬浮球把常驻控件缩小到 56dp 并支持拖动,从根本上消除了遮挡。

交互

手势 动作
单击 冻结 / 解冻
长按 「冻结设置」菜单:已冻结应用 (N) / 诊断 / 冻结系统应用开关
拖动 移动位置(8dp 阈值区分手势,拖动不会误触发冻结)
  • 位置按窗口比例持久化,跨页面、跨 Settings 进程重启保持
  • 状态色:青 = 可冻结、薄荷绿 = 已冻结、琥珀 = 系统应用(与旧药丸一致)
  • 读屏(TalkBack)保留完整动作说明,语义不回退

修复

  • 从「已冻结应用」列表解冻后,页面主按钮仍显示「已冻结」(与真实状态相反),
    现已解冻后立即重渲染。

真机验证摘要(realme RMX1971)

  • 注入:应用信息页出现悬浮球;应用管理列表页 / 通知设置页不注入;SubSettings 容器正常
  • 冻结/解冻第三方应用(SAI):enabled 1→3→1,球色即时切换
  • 拖动:位置即时跟随、松手保存、进程重启后恢复
  • 冻结系统应用:默认阻止 + 提示;三层警示完整;com.android.wallpapercropper
    完整走通 1→3→1 后恢复原状
  • 关键组件(电话 / 通信 / 蓝牙 / NFC / 网络栈 / 桌面 / 输入法)全程未触碰

升级

覆盖安装即可。此前的冻结记录与「冻结系统应用」开关均保留
(存储于宿主设置进程的 SharedPreferences)。

v1.0.2 — 界面文案跟随系统语言(中/英)

Choose a tag to compare

@zhangdunlong zhangdunlong released this 15 Oct 11:48

settings-app-freezer v1.0.2

界面文案现在跟随系统语言自动切换中文 / 英文。


本版内容

新增:界面文案跟随系统语言(中 / 英)

模块的全部界面此前固定为中文。现在会按宿主语言显示对应文案,覆盖:

  • 操作栏按钮(冻结 / 解冻 / 已冻结列表入口)
  • 「已冻结应用」列表弹窗(含空状态)
  • 全部操作提示(冻结 / 解冻 / 撤销 / 各类失败原因)
  • 长按诊断信息
  • 读屏(TalkBack)朗读内容
中文环境 英文环境
按钮 [分身] 冻结此应用 [Clone] ❄ Freeze this app
已冻结 ❄ 已冻结 0 ❄ Frozen 0
空列表 暂无已冻结应用 No frozen apps
操作结果 已冻结 微信 Frozen WeChat

关于语言来源:语言取自宿主进程的 Locale.getDefault()。Android 会把该进程所属应用的
语言配置写入进程默认值,所以在 Android 13+ 上按应用设置语言也有效 —— 例如系统是中文、
只把「设置」改成英文时,模块会跟着「设置」显示英文,与用户眼前的界面一致。

刻意不翻译的部分:用于识别系统界面的关键词(强行停止 / Force stop)保持原样。
它们必须匹配系统实际显示的文案,翻译了反而会让页面识别失效 —— 这也是英文系统下
模块能正常工作的前提。

变更:说明文案改为中英对照

以下三处统一为 中文 · English 格式:

  • LSPosed 里显示的模块描述(AndroidManifest 的 xposeddescription)
  • 模块索引页简介(SUMMARY)
  • GitHub 仓库描述

模块显示名 设置内冻结 · Settings App Freezer 本就是双语,未改动。


真机验证(OnePlus PJZ110 / Android 16 / ColorOS)

场景 结果
中文(系统默认) [分身] 冻结此应用 / ❄ 已冻结 0
英文(仅「设置」应用设为 en-US) [Clone] ❄ Freeze this app / ❄ Frozen 0
英文下页面识别 按钮正常出现(系统 UI 显示 Force stop)
英文下冻结分身 仅目标分身 user 受影响,原版不受影响
英文下解冻分身 恢复正常,日志 Unfrozen WeChat want=ENABLE readback=1
英文下空列表弹窗 No frozen apps

安装

  1. 下载下方 freezer-module.apk 覆盖安装

  2. LSPosed Manager → 模块 → 勾选 settings-app-freezer

  3. 作用域必须同时勾选以下两项:

    作用域 缺失后果
    系统框架(system) 模块开机时不注入,任何页面都不会有按钮
    设置(com.android.settings) 模块能加载,但不会 hook 任何设置进程

    ⚠️ 缺任意一项都不生效,且没有任何界面提示。

  4. 重启手机

运行要求

  • Android 8.0 (API 26) 及以上
  • LSPosed(Zygisk / NeoZygisk 环境)+ Root
  • 已验证:OnePlus PJZ110 / Android 16 (API 36) / ColorOS

相关链接


完整变更:101-1.0.1...102-1.0.2

v1.0.1 — 修复分身冻结误伤原版

Choose a tag to compare

@zhangdunlong zhangdunlong released this 15 Oct 08:02

settings-app-freezer v1.0.1

强烈建议升级 —— 本版修复了一个会误冻结原版应用的严重缺陷。


本版修复

冻结分身应用时误冻结原版(严重)

在「设置 → 应用信息」页对分身应用点击冻结时,模块会:

  • ❌ 把原版应用冻结(而不是分身)
  • ❌ 同时报告「操作未生效」,让人以为什么都没发生

也就是说,你以为只是冻结了分身,实际被停用的是主力账号里的那个应用。

根因

Android 公开 API 的重载签名是:

PackageManager.setApplicationEnabledSetting(String packageName, int newState, int flags)
//                                                                        ↑ 不是 userId

第三个参数是 flags。旧实现按「用户 id」传入:

pm.setApplicationEnabledSetting(pkg, state, cloneUserId);   // 语法合法,语义全错

用户 id 被静默塞进 flags 槽位,调用依然作用于调用方所在的用户(0,即原版)。

读取路径同样失效:公开 API 没有 getApplicationEnabledSetting(String, int),
旧代码的反射调用抛 NoSuchMethodException,状态回读恒为默认值 ——
所以界面完全无法反映分身的真实状态,也就无法及时发现写错了目标。

修复方式

改为通过用户域 Context 取得绑定到目标用户的 PackageManager:

Context userCtx = ctx.createPackageContextAsUser(ctx.getPackageName(), 0, UserHandle.of(userId));
userCtx.getPackageManager().setApplicationEnabledSetting(pkg, state, 0);

用户由 Context 决定,之后读写都用普通公开 API,不再依赖易变的隐藏接口签名。

并且加了硬性保护:拿不到目标用户的 PackageManager 时直接抛异常拒绝执行,
绝不回退到调用方作用域 —— 宁可操作失败,也不能改动错误的用户。

实测对比(OnePlus PJZ110 / Android 16 / ColorOS,微信分身 user 999)

用户 操作前 v1.0.0 v1.0.1
0(原版) enabled=1 enabled=3 被误冻结 enabled=1 ✅
998 enabled=1 enabled=1 enabled=1 ✅
999(目标分身) enabled=1 enabled=1 没冻上 enabled=3 ✅

其他

  • undoFreeze()(Toast 撤销)改为使用页面所属用户,原实现固定用当前进程用户,
    在分身页面会指回原版
  • build.sh 增加版本一致性校验:version.properties 与 AndroidManifest.xml
    不一致时直接构建失败(APK 版本实际取自 Manifest,此前无任何机制防止两者漂移)

升级前请自查

如果你在 v1.0.0 上使用过「分身冻结」,请检查对应原版应用是否被误冻结:

  • 系统设置 → 应用 → 已停用应用
  • 或本模块应用信息页底部的 「❄ 已冻结 N」 列表(点击任意行即可解冻)

安装

  1. 下载下方 freezer-module.apk 覆盖安装

  2. LSPosed Manager → 模块 → 勾选 settings-app-freezer

  3. 作用域必须同时勾选以下两项:

    作用域 缺失后果
    系统框架(system) 模块开机时不注入,任何页面都不会有按钮
    设置(com.android.settings) 模块能加载,但不会 hook 任何设置进程

    ⚠️ 缺任意一项都不生效,且没有任何界面提示。

  4. 重启手机

运行要求

  • Android 8.0 (API 26) 及以上
  • LSPosed(Zygisk / NeoZygisk 环境)+ Root
  • 已验证:OnePlus PJZ110 / Android 16 (API 36) / ColorOS

相关链接


完整变更:100-1.0.0...101-1.0.1

1.0.0

Choose a tag to compare

@zhangdunlong zhangdunlong released this 11 Oct 07:12

settings-app-freezer v1.0.0

在系统「设置 → 应用信息」页注入 冻结 / 解冻 按钮,一键停用任意用户应用。
为 LSPosed + ColorOS / RealmeUI / 现代 Android 重新实现。


这是什么

Android 8 之后官方设置里的「停用」入口被移除,冻结应用通常得靠 pm disable-user
或 Titanium Backup 这类外部工具。本模块把冻结能力直接放回你每天都会经过的
「应用信息」页面 —— 打开页面,右下角点一下,应用即冻结;从桌面消失,数据保留。

核心功能

  • 一键冻结 / 解冻 —— 应用信息页右下角浮动按钮,冻结后应用从桌面消失,数据完整保留
  • 状态一目了然 —— 未冻结青色,已冻结薄荷绿
  • 已冻结应用列表 —— 底部「❄ 已冻结 N」入口带实时计数角标,弹窗列出全部已冻结应用(图标 + 名称 + 包名),点击任意行即解冻
  • 长按诊断 —— 显示目标包名、启用状态、是否系统应用、是否被保护

深层安全保护

误冻系统组件会导致设备无法使用。本模块动态识别(非硬编码)并拒绝冻结:

  • 系统关键包 —— 设置、SystemUI、权限控制器、应用商店、GMS 等
  • 当前桌面启动器 —— 冻结它会让你没有桌面可用
  • 当前启用的输入法 —— 冻结它会让全局无法输入
  • 正在前台运行的应用

被拦截时会 Toast 明确告知原因,不会静默失败。

技术要点

ROM 无关 不 hook 任何厂商内部类名,改用 Intent 判定 + 视图布局信号
多层兜底识别 8 级包名解析路径 + normalizePackage() 归一化,最后用 getApplicationInfo() 硬验证
五层生命周期 hook onCreate / onResume / onPostResume / onNewIntent / onWindowFocusChanged / ViewRootImpl.performTraversals
跨Activity 交接 宿主销毁时把注入转交给持焦点窗口,独立 12 秒重试预算
自适应注入 20 轮短延迟重试 + 一次性 OnGlobalLayoutListener
零 Gradle 构建 纯命令行链路,无需 Android Studio

关于 ColorOS 的两段式页面(v1.0.0 重点修复)

旧版冻结类模块在现代 ROM 上失效,主因是 ColorOS 应用信息页的真实结构:

com.android.settings.applications.InstalledAppDetailsTop   ← 瞬时 Activity,启动即销毁
                    ↓ 交接
com.oplus.settings.feature.homepage.OplusSettingsHomepageActivity   ← 真正渲染,单 Activity 内换页

在 onCreate 注入时布局尚未测量(w=0 h=0),而 120ms 后的首次重试时宿主已经销毁 ——
重试窗口与页面存活窗口完全错开,按钮因此永不出现。

本版本新增 handOverToFocusedWindow():宿主销毁时把注入动作转交给当前持有焦点的窗口,
并配置独立的重试预算(实测交接目标在数秒后才真正创建)。同时新增
tryDirectInjectOnFocus():窗口获得焦点时内容已完成测量,直接注入,无需重试。

关键细节:换页过程中壳 Activity 会先停留在设置主页,应用信息内容需数百毫秒后才绘出。
因此「尚非应用信息页」这一判断必须允许重试,否则交接会在第一跳即中止 ——
这正是该 bug 反复出现的深层原因。

运行要求

  • Android 8.0 (API 26) 及以上
  • LSPosed 框架(Zygisk / NeoZygisk 环境)
  • Root 权限
  • 已验证:OnePlus PJZ110 / Android 16 (API 36) / ColorOS

安装

  1. 下载下方 freezer-module.apk 安装到手机
  2. LSPosed Manager → 模块 → 勾选 settings-app-freezer
  3. 进入模块 → 作用域 → 勾选 系统框架(system) 与 设置(com.android.settings)
    —— 两项都必须勾。缺 system 时模块不会在开机时注入,缺 com.android.settings
    时模块能加载但不会 hook 任何设置进程,且没有任何界面提示
  4. 重启手机(LSPosed 在开机时读入作用域,仅强停设置进程不够)
  5. 打开任意应用信息页,右下角即出现冻结按钮

排查提示:模块装了却毫无反应,先确认作用域两项齐全,再看日志
adb shell su -c 'grep Freezer /data/adb/lspd/log/modules_*.log | tail -50'。
完全没有 FreezerModule 日志 = 作用域未生效;有 hook 日志但无
button bar injected = 包名未解析到。

已知限制

  • 需要 Root + LSPosed,作用域改动后必须重启手机
  • 系统应用通常无法冻结 —— DISABLED_USER 对系统应用需更高权限,会被拒绝
  • 加固应用可能自我拉活 —— 部分应用带自保护机制
  • 冻结不等于删除 —— 采用框架级「停用」语义,数据完整保留
  • 其他 ROM 首次适配 —— 需提供 LSPosed 日志协助排查
  • 锁屏状态无法自证 —— 需解锁后人工确认按钮渲染

反馈

遇到问题请提交 Issue,并附上:

adb shell su -c 'grep Freezer /data/adb/lspd/log/modules_*.log | tail -50'

同时请说明设备型号、Android 版本、ROM 与 LSPosed 版本。


许可:GPL-3.0 · 源码:https://github.com/zhangdunlong/settings-app-freezer