【问题标题】:Where can I get a list of Android permissions我在哪里可以获得 Android 权限列表
【发布时间】:2010-11-21 13:08:02
【问题描述】:

我正在尝试获取有效的 Android 权限列表。我知道http://developer.android.com/reference/android/Manifest.permission.html 的“官方”消息,但似乎还有更多。

例如

android.permission.READ_SETTINGS
android.permission.ACCESS_LOCATION
android.permission.ACCESS_GPS

com.android.vending.CHECK_LICENSE

com.android.browser.permission.READ_HISTORY_BOOKMARKS
com.android.browser.permission.WRITE_HISTORY_BOOKMARKS

com.google.android.googleapps.permission.GOOGLE_AUTH
com.google.android.googleapps.permission.GOOGLE_AUTH.OTHER_SERVICES

com.google.android.c2dm.permission.RECEIVE

我在哪里可以得到这样的清单?我在哪里可以获得这些权限的说明?

【问题讨论】:

标签: android android-manifest


【解决方案1】:

adb shell pm list permissions -s

这可能就是您要找的。​​p>

【讨论】:

  • 也可以不使用-s
  • 我是否正确假设 :-) “adb shell pm list features”会列出附加设备的功能?
  • 我怎样才能看到权限的真实名称,如清单上使用的那样?
  • @androiddeveloper yupp,现在明白了。但这将是一个“新问题”;)答案:adb shell dumpsys package com.foo.bar,并在输出中跳到grantedPermissions:。下面是“完整符号”的权限,例如android.permission.INTERNET,每行一个。当然,您必须将 com.foo.bar 替换为您感兴趣的包名称;)
  • @Izzy 我会投票支持新更新的答案。谢谢你。我什至不记得我为什么问这个问题。那是很久以前的事了。
【解决方案2】:

没有所有权限的综合“列表”。任何想要强制执行自己的权限的应用程序都可以定义新权限:https://developer.android.com/guide/topics/security/security.html#declaring

Manifest.permission 类列出了“系统”权限,您已经知道这些权限。您列出的其他内容不是系统权限,而是特定于某些应用程序,或者是旧名称(例如,ACCESS_LOCATION 和 ACCESS_GPS 是 1.0 之前的名称)。

在源代码中对 <permission android:name= 之类的东西进行 grep 会显示所有包含的应用程序权限(对于开源应用程序),但通常您应该坚持记录在案的权限名称。

【讨论】:

    【解决方案3】:

    使用以下 sn-p 获取设备上声明的所有权限:

    Context context = this;
    PackageManager pm = context.getPackageManager();
    CharSequence csPermissionGroupLabel;
    CharSequence csPermissionLabel;
    
    List<PermissionGroupInfo> lstGroups = pm.getAllPermissionGroups(0);
    for (PermissionGroupInfo pgi : lstGroups) {
        csPermissionGroupLabel = pgi.loadLabel(pm);
        Log.e("perm", pgi.name + ": " + csPermissionGroupLabel.toString());
    
        try {
            List<PermissionInfo> lstPermissions = pm.queryPermissionsByGroup(pgi.name, 0);
            for (PermissionInfo pi : lstPermissions) {
                csPermissionLabel = pi.loadLabel(pm);
                Log.e("perm", "   " + pi.name + ": " + csPermissionLabel.toString());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    

    【讨论】:

    • 嗨,当我编码你的代码然后显示错误。那里说获得清单文件的所有权限。这是最好的方法吗?
    • @NirPear 您好,我在“Galaxy Note”中使用了您的代码,日志显示 android.permission.NFC 并且此设备没有 NFC。我需要获得设备的正确权限。你知道我该怎么做吗?谢谢。
    • @htafoya 我认为它显示了操作系统的所有可用权限,无论您拥有什么硬件。
    • 您缺少不在权限组中的权限。
    【解决方案4】:

    列出您手机上的所有权限

    adb shell pm list permissions -g
    

    -s 参数是一个简短的总结

    【讨论】:

    【解决方案5】:

    我在哪里可以得到这样的清单?

    你不能。

    我在哪里可以获得这些权限的说明?

    这些权限记录在哪里。在许多情况下,它们没有记录,因此不应使用。

    例如,您的前三个已在几年前从 Android 中删除,IIRC。最后一个记录在C2DM documentation

    【讨论】:

    • 我认为情况已经改变,所以现在你可以再做一次:stackoverflow.com/a/69053542/878126
    • @androiddeveloper:恕我直言,不是真的,至少在这个 11 岁的问题的背景下。您的代码 sn-p 列出了运行它的特定设备或模拟器的权限。这不是问题所要求的——它要求“有效的 Android 权限列表”。设备制造商在您正在测试的设备之外的其他设备上添加的权限是有效的。应用程序添加的权限是有效的,但您的代码仅列出您碰巧安装的应用程序的权限。等等。您的代码绝对有价值,但也有其局限性。
    • 当然。不过,您至少可以通过文档中的内容过滤它们。
    【解决方案6】:

    肯定有“更多权限”。 reference you've linked 只是“官方列表”——即便如此,它也很不完整。大约一年来,我已经研究了现有权限、它们的用途以及它们对最终用户的影响——我真的很想知道开发人员如何找到他们需要的东西。很好的猜测似乎是其中的一部分,至于许多权限,Google 搜索刚刚产生了几个应用程序的 Manifest 文件的内容(“使用......”)。

    除此之外,在“官方权限”(或者更确切地说是“Android 核心权限”)旁边,每个开发人员都可以为自己的应用定义自己的权限(正如 Charlie Collins 已经在 his answer 中指出的那样)。

    在我的研究过程中,我设置了一个列表,其中包含我从多个来源(我一并列出)的发现——添加了我能找到的任何解释。此列表相当关注最终用户,但仍可能对开发人员有所帮助。您可以在my site:Android Permissions explained 找到它——双语(英语和德语)。该列表包括“核心权限”以及一些选定的特定于应用程序的权限(主要是那些更频繁遇到的:由 Google 应用程序声明,或 TaskerK-9 Mail 等流行应用程序)。同样,这当然远非完整——“完整列表”就像独角兽一样可能(发布之日很可能已经过时了)。


    编辑:

    正如另一条评论中所要求的那样:如果您安装的软件包具有 new 任何列表尚未涵盖的权限,并且您想知道该新权限的“技术名称”,您可以通过 ADB 从您的设备中检索该信息:

    adb shell dumpsys package com.foo.bar
    

    (当然用相关包的名称替换com.foo.bar)。在输出中,跳到grantedPermissions: 行。下面是“完整符号”的权限,例如android.permission.INTERNET,每行一个。为了让这更容易:

    adb shell dumpsys package com.foo.bar |egrep -A99999 "grantedPermissions:"
    

    【讨论】:

      【解决方案7】:

      您可以使用以下代码获取设备上的所有权限:

      public static List<PermissionInfo> getAllPermissions(Context context) {
          PackageManager pm = context.getPackageManager();
          List<PermissionInfo> permissions = new ArrayList<>();
      
          List<PermissionGroupInfo> groupList = pm.getAllPermissionGroups(0);
          groupList.add(null); // ungrouped permissions
      
          for (PermissionGroupInfo permissionGroup : groupList) {
              String name = permissionGroup == null ? null : permissionGroup.name;
              try {
                  permissions.addAll(pm.queryPermissionsByGroup(name, 0));
              } catch (PackageManager.NameNotFoundException ignored) {
              }
          }
      
          return permissions;
      }
      

      【讨论】:

      • 似乎它在 Android Q 上存在问题,并且文档对于将 null 传递给 queryPermissionsByGroup 很奇怪。在此报告:issuetracker.google.com/issues/138239135issuetracker.google.com/issues/138247524
      • @androiddeveloper 这种行为是故意的。见issuetracker.google.com/issues/139012029#comment8
      • @MuntashirAkon 是的,但我仍然不明白为什么。毕竟,这只是信息......
      • @androiddeveloper 我也是。我的意思是您可以使用单个查询获得已安装应用程序的列表并将其发送“home”,但您无法获得完整的权限列表。太荒谬了!
      • 您无法获取权限列表?我以为只是他们的团体,不是吗?
      【解决方案8】:

      我知道这是一个迟到的帖子,但这更多的是为将来有同样问题的人提供参考。

      Here 是 Android 7.0 (Nougat) 中每个内置权限的列表。但是,可以创建您自己的权限,因此该列表不会包含所有权限。

      希望有帮助:)

      【讨论】:

      • 没有“迟到”的帖子 :)
      【解决方案9】:

      这取决于 Android 版本。原因是从某些 Android 版本开始,Google 注意到(或只是允许)OEM 可以更改哪个权限属于哪个权限组。根据谷歌在问题跟踪器上告诉我的内容,这至少发生在一些中国 OEM 身上(这不是他们第一次破坏行为,如 here 所示)。他们甚至可以在对操作系统进行简单更新之间进行更改。

      那么,这就是你今天所拥有的:

      1. 普通的 API(和 ./adb shell pm list permissions -s 的 adb 命令)将无法正常工作。它将提供大量权限 进入“未定义”组。原因是谷歌说它可能是 因设备和 OEM 不同而不同
      2. 您可以查看这些版本的 Android 源代码,并希望大多数设备都使用那里的源代码。以前是here,但链接是 现在死了。我想this one可以给你同样的信息 虽然(但您需要检查它使用的是哪个 Android 版本 为)。
      3. 另一种处理方法是制作您自己的示例 POC 来检查每个权限 - 它属于哪个权限组。您将通过在清单中声明所有权限(从下面的代码中获取)来完成此操作,然后请求一堆权限。如果你得到一个对话框,这意味着你选择的属于一个组,你可以继续测试更多的权限,看看它们是否也属于。如果不是,则其中至少有一个属于另一个组。

      要通过仅在系统中和/或 Android 本身中的权限进行过滤,您可以使用权限的包名称必须以“android”开头或权限组名称应以“开头”的条件android.permission 组。”或者权限的保护级别是 PermissionInfo.PROTECTION_SIGNATURE 。这取决于您希望过滤的内容。

      所以,一个简单的函数可以列出所有 Android 版本:

      enum class PermissionGroup constructor(@param:Permission @field:Permission val permissions: Array<String>) {
          //based on https://developer.android.com/reference/android/Manifest.permission_group.html, https://developer.android.com/guide/topics/permissions/requesting.html https://developer.android.com/reference/android/Manifest.permission
          // get all permissions and groups here: https://stackoverflow.com/a/51156191/878126 https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
          CALENDAR(arrayOf(permission.READ_CALENDAR, permission.WRITE_CALENDAR)),
          CAMERA(arrayOf(permission.CAMERA)),
          CONTACTS(arrayOf(permission.READ_CONTACTS, permission.WRITE_CONTACTS, permission.GET_ACCOUNTS)),
          LOCATION(sequenceOf(permission.ACCESS_COARSE_LOCATION, permission.ACCESS_FINE_LOCATION, if (VERSION.SDK_INT >= VERSION_CODES.Q) permission.ACCESS_BACKGROUND_LOCATION else null)
                  .filterNotNull().asIterable().toList().toTypedArray()),
          MICROPHONE(arrayOf(permission.RECORD_AUDIO, "android.permission.RECORD_BACKGROUND_AUDIO")),
          PHONE(sequenceOf(permission.READ_PHONE_STATE, if (VERSION.SDK_INT >= VERSION_CODES.P) permission.ACCEPT_HANDOVER else null,
                  permission.CALL_PHONE, permission.ADD_VOICEMAIL, permission.USE_SIP,
                  if (VERSION.SDK_INT >= VERSION_CODES.O) permission.ANSWER_PHONE_CALLS else null, if (VERSION.SDK_INT < VERSION_CODES.P) permission.READ_CALL_LOG else null,
                  if (VERSION.SDK_INT < VERSION_CODES.P) permission.WRITE_CALL_LOG else null, if (VERSION.SDK_INT < VERSION_CODES.P) permission.PROCESS_OUTGOING_CALLS else null,
                  if (VERSION.SDK_INT >= VERSION_CODES.O) permission.READ_PHONE_NUMBERS else null).filterNotNull().asIterable().toList().toTypedArray()),
          SENSORS(sequenceOf(if (VERSION.SDK_INT >= VERSION_CODES.KITKAT_WATCH) permission.BODY_SENSORS else null,
                  if (VERSION.SDK_INT >= VERSION_CODES.M && VERSION.SDK_INT < VERSION_CODES.P) permission.USE_FINGERPRINT else null, if (VERSION.SDK_INT >= VERSION_CODES.P) permission.USE_BIOMETRIC else null)
                  .filterNotNull().asIterable().toList().toTypedArray()),
          SMS(sequenceOf(permission.SEND_SMS, permission.RECEIVE_SMS, permission.READ_SMS, permission.RECEIVE_WAP_PUSH, permission.RECEIVE_MMS,"android.permission.READ_CELL_BROADCASTS")
                  .filterNotNull().asIterable().toList().toTypedArray()),
      
          STORAGE(sequenceOf(permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE, if (VERSION.SDK_INT >= VERSION_CODES.Q) permission.ACCESS_MEDIA_LOCATION else null)
                  .filterNotNull().asIterable().toList().toTypedArray()),
      
          CALL_LOG(if (VERSION.SDK_INT >= VERSION_CODES.P)
              arrayOf(permission.READ_CALL_LOG, permission.WRITE_CALL_LOG, permission.PROCESS_OUTGOING_CALLS)
          else emptyArray()),
      
          ACTIVITY_RECOGNITION(if (VERSION.SDK_INT >= VERSION_CODES.Q) arrayOf(permission.ACTIVITY_RECOGNITION) else emptyArray()),
      
          NEARBY_DEVICES(if (VERSION.SDK_INT >= VERSION_CODES.S) arrayOf(permission.BLUETOOTH_CONNECT, permission.BLUETOOTH_ADVERTISE, permission.UWB_RANGING, permission.BLUETOOTH_SCAN) else emptyArray())
          ;
      
          @TargetApi(VERSION_CODES.S)
          @StringDef(permission.READ_CALENDAR, permission.WRITE_CALENDAR, permission.CAMERA, permission.READ_CONTACTS, permission.WRITE_CONTACTS,
                  permission.GET_ACCOUNTS, permission.ACCEPT_HANDOVER, permission.ACCESS_COARSE_LOCATION, permission.ACCESS_FINE_LOCATION, permission.RECORD_AUDIO,
                  permission.USE_BIOMETRIC, permission.READ_PHONE_STATE, permission.CALL_PHONE, permission.READ_CALL_LOG, permission.WRITE_CALL_LOG, permission.ADD_VOICEMAIL,
                  permission.USE_SIP, permission.PROCESS_OUTGOING_CALLS, permission.BODY_SENSORS, permission.SEND_SMS, permission.RECEIVE_SMS, permission.READ_SMS, permission.RECEIVE_WAP_PUSH,
                  permission.RECEIVE_MMS, permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE, permission.ANSWER_PHONE_CALLS, permission.ACTIVITY_RECOGNITION,
                  permission.ACCESS_BACKGROUND_LOCATION, permission.ACCESS_MEDIA_LOCATION, "android.permission.RECORD_BACKGROUND_AUDIO",
                  permission.BLUETOOTH_CONNECT, permission.BLUETOOTH_ADVERTISE, permission.UWB_RANGING, permission.BLUETOOTH_SCAN,"android.permission.READ_CELL_BROADCASTS"
          )
          @Retention(AnnotationRetention.SOURCE)
          annotation class Permission
      }
      

      然后找到它们:

      fun checkPermissions() {
          var permissionsCount = 0
          when {
              Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
                  val permissionGroups = packageManager.getAllPermissionGroups(0)
                  var permissionsGroupsLeft = permissionGroups.size
                  permissionGroups.forEach { permissionGroup: PermissionGroupInfo ->
                      val permissionGroupName = permissionGroup.name
                      if (!permissionGroupName.startsWith("android.permission-group.")) {
                          if (--permissionsGroupsLeft == 0) {
                              Log.d("AppLog", "total permissions (of all permissions groups) count:$permissionsCount")
                          }
                          return@forEach
                      }
                      packageManager.getPlatformPermissionsForGroup(permissionGroupName, mainExecutor) { groupPermissions ->
                          if (groupPermissions.isNotEmpty()) {
                              Log.d("AppLog", "permissionGroup:$permissionGroupName")
                              groupPermissions.forEach { permissionName ->
                                  Log.d("AppLog", "\t\t$permissionName")
                                  ++permissionsCount
                              }
                          }
                          if (--permissionsGroupsLeft == 0) {
                              Log.d("AppLog", "total permissions (of all permissions groups) count:$permissionsCount")
                          }
                      }
                  }
                  return
              }
              Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> {
                  Log.d("AppLog", "cannot use API to query permissions, so guessing it is similar to what we have found about it:")
                  PermissionGroup.values().forEach { permissionGroup ->
                      val permissions = permissionGroup.permissions
                      if (permissions.isEmpty())
                          return@forEach
                      Log.d("AppLog", "permissionGroup:${permissionGroup.name}")
                      permissions.forEach { permissionName ->
                          Log.d("AppLog", "\t\t${permissionName}")
                          ++permissionsCount
                      }
                  }
              }
              else -> {
                  val allPermissionGroups = packageManager.getAllPermissionGroups(0)
                  allPermissionGroups.forEach { permissionGroup ->
                      val permissionGroupName = permissionGroup.name
                      if (!permissionGroupName.startsWith("android.permission-group."))
                          return@forEach
                      val groupPermissions = packageManager.queryPermissionsByGroup(permissionGroupName, 0)
                      if (groupPermissions.isEmpty())
                          return@forEach
                      Log.d("AppLog", "permissionGroup:$permissionGroupName")
                      for (permission in groupPermissions) {
                          val permissionName = permission.name
                          Log.d("AppLog", "\t\t${permissionName}")
                          ++permissionsCount
                      }
                  }
              }
          }
          Log.d("AppLog", "total permissions (of all permissions groups) count:$permissionsCount")
      }
      

      【讨论】:

        猜你喜欢
        • 2011-11-11
        • 2020-11-29
        • 2011-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多