影评周公子 2026-02-03 18:15 采纳率: 98.9%
浏览 1
已采纳

Hide-My-Applist 为何在 Android 12+ 上无法隐藏系统应用?

**问题描述:** 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.settingscom.android.dialercom.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]

    四、验证层:实证诊断命令与日志证据链

    1. adb shell dumpsys package com.android.settings | grep -E "(userId|flags|pkg)" → 显示 userId=1000(system)且 flags=[SYSTEM|PERSISTENT]
    2. adb shell pm list packages -s → 列出所有系统包,确认目标存在;
    3. adb shell cmd package resolve-activity -c android.intent.category.LAUNCHER com.android.settings → 返回 resolved activity,证明组件可被发现;
    4. 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 标准,通用性低;
    • ✅ 启动器级替代方案(推荐):利用 Launcher3LauncherAppState#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 默认启用 restrictNonSystemApps SELinux 策略,禁止非 platform_app 域访问 package_manager_service 的 hide 接口;
    • 2024 年 Android U(15)开发者预览版已移除 pm hide 的 shell 入口,仅保留 Binder 接口且 require MANAGE_PACKAGESsignature|privileged)。
    ```
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 2月4日
  • 创建了问题 2月3日