前言:
最近突然喜欢上一句诗:“宠辱不惊,看庭前花开花落;去留无意,望天空云卷云舒。” 哈哈~,这个和今天的主题无关,最近只要不学习总觉得生活中少了点什么,所以想着围绕着最近面试过程中讨论比较多的一个知识点Android 6.0 权限适配问题来进行学习,不过我不想直接进入这个主题,所以选择先去了解一下Android的Permission权限机制及使用
权限管理相关博客:
- Android权限管理之Permission权限机制及使用
- Android权限管理之Android 6.0运行时权限及解决办法
- Android权限管理之RxPermission解决Android 6.0 适配问题
Android权限机制:
权限是一种安全机制。Android权限主要用于限制应用程序内部某些具有限制性特性的功能使用以及应用程序之间的组件访问。
Android权限列表:
Android权限列表可以参考这篇博客:android权限大全
Android权限使用:
1.)在 AndroidManifest.xml <manifest>标签内使用<uses-permission>声明使用某一个权限
<uses-permission android:name="string"/>
例如申请使用网络权限
<uses-permission android:name="android.permission.INTERNET"/>
如果特定的权限必须申明使用,如果没有申请使用就会报出Permission Denial错误,例如访问通讯录报出如下错误
Caused by: java.lang.SecurityException: Permission Denial: reading com.androintacts.ContactsProvider2 uri content://contacts/data/phones from pid=23763, uid=10036 requires android.permission.READ_CONTACTS
解决此类错误我们只需根据提示添加对应的权限即可
<uses-permission android:name="android.permission.READ_CONTACTS" />
2.)自定义权限permission
虽然这种使用场景不多见,但是在有些特定的场景下出于安全考虑就需要自定义权限了,比如两个APP之间需要共享数据而采用了ContentProvider,此时我们需要对一个app访问另外一个app的数据时需要添加权限申请。自定义权限通过<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” | “signatureOrSystem”] />
android:description:对权限的描述,比lable更加的详细,介绍该权限的相关使用情况,比如当用户被询问是否给其他应用该权限时。注意描述应该使用的是string资源,而不是直接使用string串。
android:icon:用来标识该权限的一个图标。
android:label:权限的一个给用户展示的简短描述。方便的来说,这个可以直接使用一个string字串来表示,但是如果要发布的话,还是应该使用string资源来表示。
android:name:权限的唯一名字,由于独立性,一般都是使用包名加权限名,该属性是必须的,其他的可选,未写的系统会指定默认值。
android:permissionGroup: 权限所属权限组的名称,并且需要在这个或其他应用中使用<permission-group>标签提前声明该名称,如果没有声明,该权限就不属于该组。
android:protectionLevel:权限的等级
关于android:protectionLevel:权限的等级
normal 低风险权限,只要申请了就可以使用(在AndroidManifest.xml中添加<uses-permission>标签),安装时不需要用户确认;
dangerous 高风险权限,安装时需要用户的确认才可使用;
signature 只有当申请权限的应用程序的数字签名与声明此权限的应用程序的数字签名相同时(如果是申请系统权限,则需要与系统签名相同),才能将权限授给它;
signatureOrSystem 签名相同,或者申请权限的应用为系统应用(在system image中),与signature类似,只是增加了rom中自带的app的声明 ,尽量不要使用该选项,因为signature已经适合绝大部分的情况。
对于普通和危险级别的权限,我们称之为低级权限,应用申请即授予。其他两级权限,我们称之为高级权限或系统权限。当应用试图在没有权限的情况下做受限操作,应用将被系统杀掉以警示。系统应用可以使用任何权限。权限的声明者可无条件使用该权限。
根据上面的介绍我们实战一下自定义权限如下
<permission
android:name="personprovider.permission.read"
android:description="@string/personprovider_permission_read_desstring"
android:icon="@mipmap/ic_launcher"
android:label="@string/personprovider_permission_read_labestring"
android:protectionLevel="normal"/>
<permission
android:name="personprovider.permission.write"
android:description="@string/personprovider_permission_write_desstring"
android:icon="@mipmap/ic_launcher"
android:label="@string/personprovider_permission_write_labestring"
android:protectionLevel="normal"/>
3.)自定义权限组permission-group
为了方便管理某一特定功能的权限,所以我会对权限进行分组,这时我们需要通过<permission-group>自定义一个权限组
<permission-group android:description="string resource"
android:icon="drawable resource"
android:label="string resource"
android:name="string"/>
android:description 这个属性用于给权限组定义一个用户可读的说明性文本。这个文本应该比标签更长、更详细。这个属性必须要引用一个字符串资源,跟label属性不一样,它不能够使用原生的字符串。
android:icon 这个属性定义了一个代表权限的图标。这个属性要使用包含图片定义的可绘制资源来定义。
android:label 这个属性给权限组定义了一个用户可读的名称。为了开发方便,在开发时,可以直接使用原生的字符串来设置这个属性。但是,当应用程序正式发布时,应该使用字符串资源来设置,以便能够像用户界面中其他的字符串一样能够被本地化。
android:name 这个属性定义了权限组的名称,它是能够分配给<permission>元素的permissionGroup属性的名称。
上面的权限组我们可以自定义为下面这种方式:
<permission-group
android:name="personprovider.permission-group"
android:description="@string/personprovider_permission_group_desstring"
android:icon="@mipmap/ic_launcher"
android:label="@string/personprovider_permission_group_labelstring"/> <permission
android:name="personprovider.permission.read"
android:description="@string/personprovider_permission_read_desstring"
android:icon="@mipmap/ic_launcher"
android:label="@string/personprovider_permission_read_labestring"
android:permissionGroup="personprovider.permission-group"
android:protectionLevel="normal"/>
<permission
android:name="personprovider.permission.write"
android:description="@string/personprovider_permission_write_desstring"
android:icon="@mipmap/ic_launcher"
android:label="@string/personprovider_permission_write_labestring"
android:permissionGroup="personprovider.permission-group"
android:protectionLevel="normal"/>
其他关于permission-tree这里就不介绍了,这个至今没有用到过,<permission-tree>是为一组permissions声明了一个namespace。
4.)使用自定义权限
申请权限
<uses-permission android:name="personprovider.permission.read"/>
<uses-permission android:name="personprovider.permission.write"/>
在宿主上声明需要申请访问权限
<provider
android:name=".PersonProvider"
android:authorities="com.whoislcj.testsqlite.personprovider"
android:enabled="true"
android:exported="true"
android:readPermission="personprovider.permission..read"
android:writePermission="personprovider.permission..write"/>
总结:
本篇大致了解了Android的权限permission以及如何使用和自定义权限,下篇将总结学一下如何解决Android 6.0的权限的适配问题。