Android中的动态权限



我想知道第三方应用程序是否有可能向系统动态添加权限。根据这本书,它可以通过使用公共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);
}

这是我的清单文件中的内容:<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:这本书已经过时了,比棒棒糖更新的Android版本确实需要MANAGE_USERSCREATE_USERS,这两个版本的保护级别都为3(签名OrSystem)。

更长的答案:

不久前,在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,但它现在调用的方法需要。

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

最新更新