Android权限和权限组之间的链接

11
4个回答

10

可以使用PackageManager的getAllPermissionGroups()和queryPermissionsByGroup()方法来枚举整个Android权限层级。在5.1.1 (SDK 22)设备上,下面的代码生成了输出结果。被标记为“personal”的组具有groupInfo.flags == 1,并且似乎对应于Marshmallow中称为“危险”的权限组。

由于SDK级别和应用程序可以定义自定义权限的差异,不同设备上将获得不同的权限层次结构。

<code>/**
 * Uses PackageManager getAllPermissionGroups() and queryPermissionsByGroup()
 * to enumerate the Android permission hierarchy.
 */
private void showPermissionTree()
{
    final PackageManager pm = m_context.getPackageManager();
    if (pm == null)
        return;

    /*
     * Get a list of all permission groups and sort them alphabetically.
     * Then add to the end of the list the special case of a null group name. There can be
     * numerous permissions that are not listed under a group name.
     */
    List<PermissionGroupInfo> groupInfoList = pm.getAllPermissionGroups(0);
    if (groupInfoList == null)
        return;

    ArrayList<String> groupNameList = new ArrayList<>();
    for (PermissionGroupInfo groupInfo : groupInfoList) {
        String groupName = groupInfo.name;
        if (groupName != null) {
            if (Build.VERSION.SDK_INT >= 17) {
                /*
                 * SDK 17 added the flags field. If non-zero, the permission group contains
                 * permissions that control access to user personal data.
                 * N.B. These are the permissions groups that are called "dangerous" in
                 * Marshmallow.
                 */
                if (groupInfo.flags != 0) {
                    groupName += " (personal)";
                }
            }
            groupNameList.add(groupName);
        }
    }

    Collections.sort(groupNameList);
    groupNameList.add(null);

    /*
     * Loop though each permission group, adding to the StringBuilder the group name and
     * the list of all permissions under that group.
     */
    StringBuilder sb = new StringBuilder(10000);
    final String INDENT = "   ";

    for (String groupName : groupNameList) {
        if (groupName == null)
            groupName = "null";

        sb.append("* ").append(groupName).append("\n");

        ArrayList<String> permissionNameList = getPermissionsForGroup(groupName);
        if (permissionNameList.size() > 0) {
            for (String permission : permissionNameList) {
                sb.append(INDENT).append(permission).append("\n");
            }
        } else {
            sb.append(INDENT).append("no permissions under group\n");
        }

        sb.append("\n");
    }

    m_textView.setText(sb.toString());
}


/*
 * Gets and returns a list of all permission under the specified group, sorted alphabetically.
 *
 * N.B. groupName can be null. The docs for PackageManager.queryPermissionsByGroup() say
 * "Use null to find all of the permissions not associated with a group."
 */
private ArrayList<String> getPermissionsForGroup(String groupName)
{
    final PackageManager pm = m_context.getPackageManager();
    final ArrayList<String> permissionNameList = new ArrayList<>();

    try {
        List<PermissionInfo> permissionInfoList =
                pm.queryPermissionsByGroup(groupName, PackageManager.GET_META_DATA);
        if (permissionInfoList != null) {
            for (PermissionInfo permInfo : permissionInfoList) {
                String permName = permInfo.name;
                if (permName == null) {
                    permName = "null";
                } else if (permName.isEmpty()) {
                    permName = "empty";
                }
                permissionNameList.add(permName);
            }
        }
    }
    catch (PackageManager.NameNotFoundException e) {
        // e.printStackTrace();
        Log.d(TAG, "permissions not found for group = " + groupName);
    }

    Collections.sort(permissionNameList);

    return permissionNameList;
}
</code>

* android.permission-group.ACCESSIBILITY_FEATURES
   该组无权限要求。
* android.permission-group.ACCOUNTS (个人信息) 该组无权限要求。
* android.permission-group.AFFECTS_BATTERY android.permission.CHANGE_WIFI_MULTICAST_STATE android.permission.FLASHLIGHT android.permission.TRANSMIT_IR android.permission.VIBRATE android.permission.WAKE_LOCK
* android.permission-group.APP_INFO android.permission.GET_TASKS android.permission.KILL_BACKGROUND_PROCESSES android.permission.MANAGE_ACTIVITY_STACKS android.permission.PERSISTENT_ACTIVITY android.permission.REAL_GET_TASKS android.permission.RECEIVE_BOOT_COMPLETED android.permission.REMOVE_TASKS android.permission.REORDER_TASKS android.permission.RESTART_PACKAGES
* android.permission-group.AUDIO_SETTINGS android.permission.MODIFY_AUDIO_SETTINGS
* android.permission-group.BLUETOOTH_NETWORK android.permission.BLUETOOTH android.permission.BLUETOOTH_ADMIN android.permission.BLUETOOTH_MAP android.permission.BLUETOOTH_PRIVILEGED
* android.permission-group.BOOKMARKS (个人信息) 该组无权限要求。
* android.permission-group.CALENDAR (个人信息) 该组无权限要求。
* android.permission-group.CAMERA (个人信息) 该组无权限要求。
* android.permission-group.COST_MONEY 该组无权限要求。
* android.permission-group.DEVELOPMENT_TOOLS android.permission.ACCESS_ALL_EXTERNAL_STORAGE android.permission.CHANGE_CONFIGURATION android.permission.DUMP android.permission.READ_LOGS android.permission.SET_ALWAYS_FINISH android.permission.SET_DEBUG_APP android.permission.SET_PROCESS_LIMIT android.permission.SIGNAL_PERSISTENT_PROCESSES android.permission.WRITE_SECURE_SETTINGS com.android.chrome.permission.DEBUG
* android.permission-group.DEVICE_ALARMS (个人信息) 该组无权限要求。
* android.permission-group.DISPLAY android.permission.SYSTEM_ALERT_WINDOW
* android.permission-group.HARDWARE_CONTROLS android.permission.ACCESS_FM_RADIO android.permission.ACCESS_MTP android.permission.HARDWARE_TEST android.permission.MANAGE_USB
* android.permission-group.LOCATION (个人信息) 该组无权限要求。
* android.permission-group.MESSAGES (个人信息) 该组无权限要求。
* android.permission-group.MICROPHONE (个人信息) 该组无权限要求。
* android.permission-group.NETWORK android.permission.ACCESS_NETWORK_STATE android.permission.ACCESS_WIFI_STATE android.permission.ACCESS_WIMAX_STATE android.permission.BROADCAST_NETWORK_PRIVILEGED android.permission.CHANGE_NETWORK_STATE android.permission.CHANGE_WIFI_STATE android.permission.CHANGE_WIMAX_STATE android.permission.CONNECTIVITY_INTERNAL android.permission.DOWNLOAD_WITHOUT_NOTIFICATION android.permission.INTERNET android.permission.LOOP_RADIO android.permission.NFC android.permission.READ_WIFI_CREDENTIAL android.permission.RECEIVE_DATA_ACTIVITY_CHANGE android.permission.SCORE_NETWORKS com.android.vending.BILLING com.android.vending.CHECK_LICENSE com.google.android.c2dm.permission.RECEIVE com.google.android.c2dm.permission.SEND com.google.android.gtalkservice.permission.SEND_HEARTBEAT com.google.android.permission.BROADCAST_DATA_MESSAGE com.google.android.xmpp.permission.BROADCAST com.google.android.xmpp.permission.SEND_RECEIVE com.google.android.xmpp.permission.USE_XMPP_ENDPOINT com.google.android.xmpp.permission.XMPP_ENDPOINT_BROADCAST com.gsma.services.nfc.permission.TRANSACTION_EVENT
* android.permission-group.PERSONAL_INFO (个人信息) 该组无权限要求。
* android.permission-group.PHONE_CALLS (个人信息) 该组无权限要求。
* android.permission-group.SCREENLOCK (个人信息) 该组无权限要求。
* android.permission-group.SOCIAL_INFO (个人信息) 该组无权限要求。
* android.permission-group.STATUS_BAR android.permission.EXPAND_STATUS_BAR
* android.permission-group.STORAGE (个人信息) 该组无权限要求。
* android.permission-group.SYNC_SETTINGS android.permission.READ_SYNC_SETTINGS android.permission.READ_SYNC_STATS android.permission.WRITE_SYNC_SETTINGS
* android.permission-group.SYSTEM_CLOCK android.permission.SET_TIME_ZONE
* android.permission-group.SYSTEM_TOOLS android.permission.ACCESS_LOCATION_EXTRA_COMMANDS android.permission.ACCESS_MOCK_LOCATION android.permission.ACCESS_PDB_STATE

很棒的代码片段。或许值得更新回答?因为在Android P(9.0)中添加了一个新的CALL_LOG权限组,其中包含PROCESS_OUTGOING_CALLS、READ_CALL_LOG和WRITE_CALL_LOG。这些权限已从PHONE组移动。 - scottyab
很遗憾,这个算法现在效果不佳。许多权限没有分配到权限组中,而许多权限组也缺少权限。 - android developer

7
Android源代码包含默认权限组和权限之间的实际映射关系。

https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml

如果您想要从权限组到权限的映射,可以获取您正在使用的Android版本的AndroidMainifest.xml文件并解析XML以创建映射。 因此,回答您的问题是,这是可能的,但听起来这可能对您的任务来说过于复杂。

更新:因为我自己在另一个项目中需要这个映射,所以我决定分享我的代码来创建这个映射。您可以在github存储库中查看结果。

链接: https://github.com/benjholla/AndroidPermissionAttributeMapper


更新2:

我的团队开源了我们的解决方案,可以生成此映射以及Android权限文档中的其他对象包装器。项目页面上有一些教程和Github存储库。

项目页面: https://ensoftcorp.github.io/android-essentials-toolbox/

源代码: https://github.com/EnSoftCorp/android-essentials-toolbox


2
在API指南中有一张表格,但只针对危险权限:
https://developer.android.com/guide/topics/security/permissions.html#perm-groups

可悲的是,即使在这种情况下,许多权限也被归为“未定义”,尽管它们明显不属于那里。例如,“WRITE_EXTERNAL_STORAGE”。 - android developer

0
据我所知:Manifest.permission_group * AB * = Manifest.permission * A * + Manifest.permission * B *,看看这个例子: < p > < code >android.permission-group.MESSAGES< /code > = < code >SEND_SMS + WRITE_SMS + RECEIVE_SMS + READ_SMS + BROADCAST_SMS< /code >< /p >

希望你已经明白了。


这是将个人权限组合成组的方法。我想知道在开发者论坛中是否已经存在组和个人权限之间的映射。例如,有一个名为BLUETOOTH_NETWORK的权限组。该组很可能包含三个权限,即BLUETOOTHBLUETOOTH_ADMINBLUETOOTH_PRIVILEGED。我自己进行了映射。如果有任何资源可用,我想完成映射。 - Faheem
@Faheem 我不知道用法,但任何人都可以将权限映射到权限组。使用页面上提供的描述来搜索关键词。例如,搜索“短信”,你会找到相关的权限。 - Shervin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接