AppOps:权限之上的细粒度隐私开关
2026/8/9大约 3 分钟权限与安全Android 14AppOps隐私权限
AppOps:权限之上的细粒度隐私开关
上一章看了权限模型。这一章回答:AppOps 是什么,它和权限什么关系,为什么权限授予了 某些操作还是被限制?
AppOps 控制操作,不替代权限
| 常见误解 | 正确理解 |
|---|---|
| AppOps 就是权限 | 权限决定“能不能要”,AppOps 决定“这次操作允不允许” |
| 权限授予了就一定能用 | 还要看 AppOps 模式,可能被 ignore/deny |
| AppOps 只有系统能碰 | 应用可通过 API 检查自己的操作状态 |
核心结论
- 每个敏感操作对应一个 op,例如相机、位置、剪贴板读取。
- 模式:allow(放行)、ignore(静默拒绝)、deny(拒绝并反馈)、default(默认)。
- 权限检查通过后,AppOps 再按 op 模式判定。
- 状态持久化在 appops.xml,用户可在设置中调整。
- 排查“权限有但操作失败”先查 AppOps 模式。
检查主链
逐步解释:
- 权限检查:先确认应用有对应权限。
- AppOps 检查:再按 op 模式判定。
- 结果:allow 放行,ignore/deny 拒绝,反馈不同。
ignore 与 deny 的区别
ignore 静默拒绝,应用可能察觉不到(API 返回空或失败但无异常);deny 明确拒绝, 通常会让应用感知失败。排查时如果“权限有但拿不到数据”,先看是不是 ignore。
源码证据
阅读目标:确认 AppOps 的检查入口与模式定义。
正文指针:AppOpsManager.java 的检查方法;AppOpsService.java 的模式管理。
// AppOpsManager.java(伪代码,行号以 r75 为准)
public static final int MODE_ALLOWED = 0;
public static final int MODE_IGNORED = 1;
public static final int MODE_ERRORED = 2; // deny
public static final int MODE_DEFAULT = 3;这段代码证明: op 模式是核心状态;权限授予之外,每次敏感操作都要按模式判定。
验证与排障
环境:开发设备或模拟器;以下命令不需要 root。
adb shell dumpsys appops
adb shell dumpsys appops | grep <包名>
adb shell cmd appops get <包名> CAMERA先看目标包的所有 op 状态,再针对具体 op 查模式。权限有但操作失败时,AppOps 是 第二个必查点。
常见误区
- “AppOps 就是权限”:两者职责不同。
- “ignore 会被应用发现”:ignore 是静默拒绝。
- “AppOps 状态不持久化”:存在 appops.xml。
- “所有权限都有对应 op”:并非一一对应,op 是独立模型。
延伸问题
- appop 与权限如何映射(如 CAMERA 权限对应多个 op)?
- 隐私面板如何汇总 AppOps 使用记录?
- 应用如何查询自己的 AppOps 状态并优雅降级?
- 系统应用与第三方应用的 AppOps 检查有什么差异?
源码入口
| 文件 | 关键位置 | 作用 |
|---|---|---|
AppOpsManager.java | 检查方法 | 应用侧 API |
AppOpsService.java | 模式管理 | 状态与策略 |
appops.xml | /data/system/ | 持久化 |
cmd appops | 命令行 | 排障入口 |
公共路径:frameworks/base/core/java/android/app/ 与 frameworks/base/services/core/java/com/android/server/appop/。行号以 r75 检索为准。
内核强制访问控制如何继续判定,见 SELinux。