权限标签 permission 和 uses-permission

最近在项目中遇到一个问题,不同的包在安装时有冲突,后一个安装的应用会被提示已经有相同的权限被声明了,因此无法安装。看了下两个包的 AndroidManifest.xml 文件,确实有相同名称的 <permission><uses-permission> 标签。那么这个 <permission> 标签和 <uses-permission> 标签有什么区别呢?

权限

首先,什么是权限?我有一个应用A,一个应用B,现在应用A想使用应用B的一些功能,那么Android系统为了安全起见,肯定不能让我们随便就调用了。应用B必须先声明一些权限,对应于开放给外界调用的功能。应用A要用,必须要先注册这些权限,相当于获取了一块通行证。

我们在 AndroidManifest.xml 文件中所见到的权限标签有两种, <permission><uses-permission> 。他们的区别,在官网文档有很详细的解释:

<permission>

<uses-permission>

大概总结一下,就是 <permission> 标签用来声明、定义一个权限,而 <uses-permission> 标签用来申请一个权限。除此之外,还有一些权限相关的标签,比如 <permission-group><permission-tree> ,这两个都是和 <permission> 相关的。其中 <permission-group> 用来声明一个权限组,在定义单个具体权限时可以将其分配到指定的权限组中,这样一个权限组就包含了多个具体权限。当申请权限组中一个单个权限成功时,同一个组内的其他权限也会自动获取到,可谓“一荣俱荣”。另外一个标签 <permission-tree> 则是为一组权限声明一个基础的命名空间,相当于一组权限的前缀,是可以用代码动态添加的,而且其名字必须要至少两个 . 符号。

permission

<permission android:description="string resource" <!--描述信息(展示给用户)-->
            android:icon="drawable resource" 
            android:label="string resource" <!--权限的名称(展示给用户)-->
            android:name="string" <!--权限的名称(唯一标示)-->
            android:permissionGroup="string" <!--所属权限组-->
            android:protectionLevel=["normal" | "dangerous" | <!--权限等级-->
                                     "signature" | ...] />

这里要注意一点, name 属性必须是唯一的!官方文档是这么说的:

Note: The system does not allow multiple packages to declare a permission with the same name, unless all the packages are signed with the same certificate. If a package declares a permission, the system does not permit the user to install other packages with the same permission name, unless those packages are signed with the same certificate as the first package. To avoid naming collisions, we recommend using reverse-domain-style naming for custom permissions, for example com.example.myapp.ENGAGE_HYPERSPACE.

也就是说,这一名称在系统中是唯一的,他是什么在系统中注册的就是什么,和你的包名什么的没有关系。因此Google建议采用和包名类似的命名方式。

此外, protectionLevel 这一属性表示这一权限的等级,不同等级的权限有不同的待遇:

  • normal: 任何应用都可以申请这一权限,而且在安装时默认授予,不会直接给用户提示
  • dangerous:任何应用都可以申请这一权限,但是会给用户提示,在5.0 6.0以后的系统,甚至需要应用动态获取,而无法再安装时一次获取
  • signature:只有与声明这一权限的应用使用了相同的私钥签名的应用才可以申请。
  • signatureAndSystem:除了满足signature的应用可以申请外,存放在系统目录 /system/app 目录下也可以申请。

难怪我们安装时会提示权限冲突,原来是因为有两个 <permission> 标签使用了相同的 name 值。

uses-permission

<uses-permission> 权限的相关属性就简单的多:

<uses-permission android:name="string" <!--权限名称-->
        android:maxSdkVersion="integer" /> <!--权限需要的最大Sdk版本-->

这里的 name 属性所指的便是由 <permission> 标签所声明时使用的 name 属性了。

所以权限冲突和这一标签是没关系的。亲测之后发现,只要不存在相同的 <permission> ,即使存在两个一样的 <uses-permission> 也是可以的。

举个栗子

在源码目录的 frameworks/base/core/ 目录下的 AndroidManifest.xml 文件中,声明了一些系统常见的权限。这儿截取一部分来看:

 <!-- ====================================================================== -->
    <!--                          RUNTIME PERMISSIONS                           -->
    <!-- ====================================================================== -->
    <eat-comment />

    <!-- ====================================================================== -->
    <!-- Permissions for accessing user's contacts including personal profile   -->
    <!-- ====================================================================== -->
    <eat-comment />

    <!-- Used for runtime permissions related to user's contacts and profile. -->
    <permission-group android:name="android.permission-group.CONTACTS"
        android:icon="@drawable/perm_group_contacts"
        android:label="@string/permgrouplab_contacts"
        android:description="@string/permgroupdesc_contacts"
        android:priority="100" />

    <!-- Allows an application to read the user's contacts data.
        <p>Protection level: dangerous
    -->
    <permission android:name="android.permission.READ_CONTACTS"
        android:permissionGroup="android.permission-group.CONTACTS"
        android:label="@string/permlab_readContacts"
        android:description="@string/permdesc_readContacts"
        android:protectionLevel="dangerous" />

    <!-- Allows an application to write the user's contacts data.
         <p>Protection level: dangerous
    -->
    <permission android:name="android.permission.WRITE_CONTACTS"
        android:permissionGroup="android.permission-group.CONTACTS"
        android:label="@string/permlab_writeContacts"
        android:description="@string/permdesc_writeContacts"
        android:protectionLevel="dangerous" />

拿通讯录权限举例。首先这里声明了一个权限组 android.permission-group.CONTACTS 。之后,分别定义了一个通讯录的读权限、一个通讯录的写权限,且他们的 permissionGroup 属性都指向了刚刚声明的权限组名称。因此,这两个权限便同属于一个权限组。此外,看看 labeldescription 属性的值是什么。在同级的 res 目录下可以看到各种语言版本的 strings.xml 文件,看看中文版怎么说吧:

<string name="permlab_readContacts" msgid="8348481131899886131">"读取您的通讯录"</string>

<string name="permdesc_readContacts" product="tablet" msgid="5294866856941149639">"允许该应用读取您平板电脑上存储的联系人的相关数据,包括您通过打电话、发送电子邮件或以其他方式与特定个人通信的频率。此权限可让应用保存您的联系人数据,而恶意应用可能会在您不知情的情况下分享联系人数据。"</string>

<string name="permdesc_readContacts" product="tv" msgid="1839238344654834087">"允许应用读取您的电视上存储的联系人相关数据,包括您与特定联系人通话、发送电子邮件或通过其他方式进行通信的频率。此权限可让应用保存您的联系人数据,而且恶意应用可能会在您不知情的情况下分享联系人数据。"</string>

<string name="permdesc_readContacts" product="default" msgid="8440654152457300662">"允许该应用读取您手机上存储的联系人的相关数据,包括您通过打电话、发送电子邮件或以其他方式与特定个人通信的频率。此权限可让应用保存您的联系人数据,而恶意应用可能会在您不知情的情况下分享联系人数据。"</string>

<string name="permlab_writeContacts" msgid="5107492086416793544">"修改您的通讯录"</string>

<string name="permdesc_writeContacts" product="tablet" msgid="897243932521953602">"允许该应用修改您平板电脑上存储的联系人的相关数据,包括您通过打电话、发送电子邮件或以其他方式与特定联系人通信的频率。此权限可让应用删除联系人数据。"</string>

<string name="permdesc_writeContacts" product="tv" msgid="5438230957000018959">"允许应用修改您的电视上存储的联系人相关数据,包括您与特定联系人通话、发送电子邮件或通过其他方式进行通信的频率。此权限可让应用删除联系人数据。"</string>

<string name="permdesc_writeContacts" product="default" msgid="589869224625163558">"允许该应用修改您手机上存储的联系人的相关数据,包括您通过打电话、发送电子邮件或以其他方式与特定联系人通信的频率。此权限可让应用删除联系人数据。"</string>

就很清楚了,在应用主动请求获取这一权限时,会弹出一个dialog,询问用户是否给予这一权限。而dialog的内容,便是由这儿的 labeldescription 组成的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351