Android

时间:2017-01-26 23:55:08

标签: android android-permissions

我想知道第三方应用是否可以动态添加系统权限。根据{{​​3}},可以通过使用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);
}

这是我在清单文件中的内容: <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)

非常感谢!

1 个答案:

答案 0 :(得分:3)

TL; DR:这本书已经过时,比Lollipop更新的Android版本确实需要MANAGE_USERSCREATE_USERS,两者的 protectionLevel 均为3(< EM> 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表示该例外来自getPrimaryUser中的getUsersUserManagerService方法。

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

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