android - Android 中的动态权限

标签 android android-permissions

我想知道第三方应用是否可以动态添加系统权限。根据this book ,可以通过使用 public addPermission() API;但是,我收到一个 SecurityException,上面写着“java.lang.SecurityException:您需要 MANAGE_USERS 或 CREATE_USERS 权限才能:查询用户”。我只是想确保它真的是因为系统不允许,而不是因为我在代码中搞砸了。如果是这样,则不允许对未使用系统证书签名的第三方应用程序动态添加权限,如果有人能解释这种选择背后的原因,那就太好了。

以下是我如何以编程方式添加权限:

public void addDynamicPermission() {
    PermissionInfo pi = new PermissionInfo();
    pi.name = "com.somedomain.permission.MY_PERMISSION";
    pi.labelRes = R.string.permission_label;
    pi.protectionLevel = PermissionInfo.PROTECTION_DANGEROUS;
    final PackageManager packageManager = getApplicationContext().getPackageManager();
    packageManager.addPermission(pi);
}

这是我的 list 文件中的内容: <permission-tree android:name="com.somedomain.permission" />

这是异常的完整 java 堆栈:

FATAL EXCEPTION: main
Process: com.example.myapp, PID: 11824
java.lang.SecurityException: You either need MANAGE_USERS or CREATE_USERS permission to: query users
at android.os.Parcel.readException(Parcel.java:1684)
at android.os.Parcel.readException(Parcel.java:1637)
at android.content.pm.IPackageManager$Stub$Proxy.addPermission(IPackageManager.java:2870)
at android.app.ApplicationPackageManager.addPermission(ApplicationPackageManager.java:535)
at com.example.myapp.MainActivity.addDynamicPermission(MainActivity.java:183)
at com.example.myapp.MainActivity$6.onClick(MainActivity.java:64)
at android.view.View.performClick(View.java:5637)
at android.view.View$PerformClick.run(View.java:22429)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

非常感谢!

最佳答案

TL;DR:这本书已经过时了,比 Lollipop 更新的 Android 版本确实需要 MANAGE_USERSCREATE_USERS,它们都有一个protectionLevel 共 3 个 (signatureOrSystem)。

更长的答案:

前段时间,在 KitKat 时代,我写了一些与您类似的测试代码,我记得它运行良好。那是几年前的事了。我刚刚在当前的 Nougat (7.0) 环境中启动了那个旧应用程序,结果出现了与您所看到的完全相同的异常。出于好奇,我重新安装了 KitKat (4.4.4)、Lollipop (5.1) 和 Marshmallow (6.0) 实例,并在每个实例上尝试了该应用程序。

对于 4.4.4 和 5.1,一切正常。我通过运行代码验证了这一点,然后检查自定义权限是否存在,如下所示:

% adb shell dumpsys package packagename | grep -i com.example
...
Permission [com.example.permission.TEST_PERMISSION] (79c4d6d):
sourcePackage=com.example.myapplication
perm=Permission{2c725da2 com.example.permission.TEST_PERMISSION}
...

但是,在 6.0 和 7.0 上,我遇到了安全异常。快速检查 androidxref.com指示异常来自 UserManagerService 中的 getPrimaryUsergetUsers 方法。

getPrimaryUsers 在 4.4.4 或 5.1 中不存在,getUsers 一直受到 checkManageOrCreateUsersPermission 的保护。因此,我认为可以合理地假设 addPermission 链从 6.0 开始被修改以出于某种原因获取用户列表。所以 addPermission 不需要 MANAGE_USERSCREATE_USERS,但它现在调用的方法需要。

这个额外的访问控制检查是否有意以及背后的原因是我无法回答的问题。

关于android - Android 中的动态权限,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41885102/

相关文章:

android - "This Feature is not available on this device"请求 DND 权限时出现此错误

android - 我想问为什么将空适配器设置为回收站 View 很重要?有什么优势吗?有什么缺点吗?

javascript - Eclipse 中的 PhoneGap Android 项目引用

java - 当我想用真实设备测试我的应用程序时,该应用程序无法启动

android - java.exe 以非退出值 2 结束

android - 无法在 Wear OS Samsung Galaxy Watch 4 上请求蓝牙权限

android - Chrome 自定义标签初始 Okta Auth 不重定向回来

java - 如何让应用程序每次运行时都请求位置权限?

棉花糖或更高版本的窗口类型 2010 的 Android 权限被拒绝

android - 读取和写入外部存储权限不起作用