**问题描述:**
Hide-My-Applist 在 Android 12+ 上无法隐藏系统应用(如“设置”“电话”“信息”等),即使已授予无障碍服务、设备管理员或ADB权限,应用图标仍出现在启动器中,且`pm hide`命令返回`Operation not allowed`错误。根本原因在于 Android 12(API 31)起强制启用**Package Visibility Restriction**与**Scoped Storage增强策略**,同时系统应用默认标记为`android:exported="true"`且受`SYSTEM_APP`签名/特权保护;Hide-My-Applist 依赖的旧版隐藏机制(如`PackageManager.setApplicationEnabledSetting()`或`pm hide`)被系统级限制拦截——非平台签名或未声明``(需系统级权限)的应用无法修改系统应用可见性。此外,Android 12+ 移除了对非系统应用调用`setComponentEnabledSetting()`影响系统包的能力,导致该工具核心逻辑彻底失效。
1条回答 默认 最新
薄荷白开水 2026-02-03 18:16关注```html一、现象层:典型故障表现与复现路径
- 在 Android 12(API 31)及以上设备上,Hide-My-Applist 对预装系统应用(如
com.android.settings、com.android.dialer、com.android.mms)执行“隐藏”操作后,桌面启动器图标无变化; - ADB 执行
adb shell pm hide com.android.settings返回Operation not allowed: package not owned by caller; - 无障碍服务已启用、设备管理员权限已授予、
adb root成功,但依然失败; - 非系统应用(如用户安装的微信、Chrome)可正常隐藏,验证工具基础功能未损坏。
二、机制层:Android 12+ 权限模型演进的核心约束
自 Android 12 起,以下三项底层机制协同构成“不可绕过”的系统级防护:
机制名称 影响范围 对 Hide-My-Applist 的直接拦截点 Package Visibility Restriction 应用无法探测/操作未在 <queries>中声明的目标包工具无法枚举系统应用组件(如 Launcher Activity),导致 setComponentEnabledSetting()缺失目标Scoped Storage 强化 + pm hide权限收窄pm hide/unhide仅允许android.permission.CHANGE_COMPONENT_ENABLED_STATE+android.permission.PACKAGE_USAGE_STATS+ 同一签名或系统级 UID第三方应用无 platform签名,无法通过 ADB 或 Runtime 调用隐藏系统包SYSTEM_APP 特权隔离 系统应用默认标记 android:exported="true"且受signature|privileged级别保护旧版 setApplicationEnabledSetting()被 Framework 层PackageManagerService.enforceSystemOrRootCaller()显式拒绝三、架构层:Hide-My-Applist 原有逻辑链断裂分析
其传统流程依赖于三层调用栈,而 Android 12+ 在第②和③层插入硬性校验:
graph LR A[UI触发“隐藏设置”] --> B[调用 PackageManager.setComponentEnabledSetting
(目标:com.android.settings/.SettingsActivity)] B --> C[Framework:PMS.checkComponentPermission
→ 检查 caller UID 是否为 SYSTEM_UID 或 ROOT_UID] C --> D{是否通过?} D -- 否 --> E[抛出 SecurityException:
“Calling uid XXX is not system or root”] D -- 是 --> F[修改 ComponentInfo.enabled = false]四、验证层:实证诊断命令与日志证据链
adb shell dumpsys package com.android.settings | grep -E "(userId|flags|pkg)"→ 显示userId=1000(system)且flags=[SYSTEM|PERSISTENT];adb shell pm list packages -s→ 列出所有系统包,确认目标存在;adb shell cmd package resolve-activity -c android.intent.category.LAUNCHER com.android.settings→ 返回 resolved activity,证明组件可被发现;adb logcat -b events | grep "package_changed"→ 执行 hide 后无事件输出,证实调用未进入 PMS 处理管道。
五、解法层:可行路径的可行性分级评估
- ❌ Root + Magisk 模块(如 Hide My Applist Mod):需重写 /system/priv-app 或注入 Zygote,兼容性差、OTA 后失效;
- ⚠️ ADB +
adb shell settings put global hidden_apps_list "com.android.settings,...":部分 OEM(如 Samsung One UI)支持私有属性,但非 AOSP 标准,通用性低; - ✅ 启动器级替代方案(推荐):利用
Launcher3的LauncherAppState#addIconToDatabase钩子或 Nova Launcher 的“隐藏应用”功能——不触碰 PackageManager,规避所有系统限制; - ✅ 系统级定制(企业/ROM 场景):在 AOSP 源码中为
PackageManagerService添加白名单机制(需android.permission.HIDE_SYSTEM_APPS自定义权限并签名升级)。
六、演进层:Android 13–14 的进一步强化趋势
Google 持续收紧边界:
- Android 13 引入
android:hasFragileUserData="true"进一步限制pm clear对系统应用的影响; - Android 14 默认启用
restrictNonSystemAppsSELinux 策略,禁止非 platform_app 域访问package_manager_service的 hide 接口; - 2024 年 Android U(15)开发者预览版已移除
pm hide的 shell 入口,仅保留 Binder 接口且 requireMANAGE_PACKAGES(signature|privileged)。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 在 Android 12(API 31)及以上设备上,Hide-My-Applist 对预装系统应用(如