@
woyaojizhu8 是的, AppOps 的设定与 Runtime Permission 的设定是分离的,即应用进行某个操作,需要两者都允许。
而这就是一些流氓应用的滥用行为可以通过 AppOps 阻止的原因:
它只检查了 Runtime Permission ,但没有考虑 AppOps ,而 AppOps 层面恰好可以设置让 API 返回空值的(将某个 OP 设置为 ignore ,这个做法是针对 target API level 低于 Android 6.0 的旧版应用设计的)。
Runtime Permission 的具体实现是 AppOps 。
有一些不属于 Runtime Permission 的,但又是系统在默认情况下就允许用户修改的权限设置,如“修改系统设置”,“在其它应用前面显示”等实际上就是直接在修改 AppOps 设定。
AppOps 的权限和 Android.permission 权限的区别应该是这样的:
如果应用没有声明 Android.permission 里的对象,那么它在试图使用这个对象制约的 API 时候会抛出 SecurityException 异常。
对于 target API 是 Android 6.0 及以上的应用,如果出现了在 Android.permission 声明但没有获得 Runtime Permission 时,直接调用对应的 API 也会抛出 SecurityException 。系统为应用提供了 API ,应用可以在任何时候检查自身是否获得了 Runtime Permission 的授权。不给权限就关闭的流氓做法就是靠这个机制实现的。
对于 target API 低于 Android 6.0 的应用,如果出现在 Android.permission 声明但没有获得 Runtime Permission 时,直接调用对应的 API 则会通过“ silent fail ”的形式达到阻止的目的:不会抛出 SecurityException ,但 API 返回的数据是空的(null ,或者是内容为空的对象)。
silent fail 对于用户来说是一件好事(特别是当我们没有一个迫使开发商不能作出“不给权限就关闭”行为的应用商店时),这个时候应用难以知道自己是否获得了权限,如此可以增加其滥用权限机制的困难程度。