您的位置:首页 > 移动开发 > Android开发

Android M版本和非M版本动态权限适配方案

2015-10-13 20:25 806 查看
动态权限适配方案
1. 背景

目前在Google官方推出的最新的AndroidM版本上,对于应用权限的调用做了大大的修改。在M版本之前,应用App需要用到什么权限只需要在AndroidManifest.xml配置文件中增加相对应权限的配置,然后在App中就可以随便无限制的使用这些权限来访问用户的设备了。由于这种权限的漏洞,导致了大量的用户信息的泄露。所以在M版本上,Android官方团队重新修改了这个权限的申请方式。在新的权限模式之下,用户将能够根据自己的实际需要在运行时中对各项权限进行审核,且随时关闭其中的部分权限。
在M版本中,Android权限被分为了3大类,默认权限、签名权限和危险权限,其中默认权限和签名权限都为安装时权限,即只要在AndroidManifest.xml中配置,就可以在app运行时放心大胆的使用。但是对于危险权限,不仅要再AndroidManifest.xml中配置,还要在代码中动态去申请,因为这些权限不是默认就授予的,而是运行时去向用户申请的。
危险权限又可以分为几组,详细分组如下:
Permission Group
Permissions
android.permission-group.CALENDAR
· android.permission.READ_CALENDAR
· android.permission.WRITE_CALENDAR
android.permission-group.CAMERA
· android.permission.CAMERA
android.permission-group.CONTACTS
· android.permission.READ_CONTACTS
· android.permission.WRITE_CONTACTS
· android.permission.GET_ACCOUNTS
android.permission-group.LOCATION
· android.permission.ACCESS_FINE_LOCATION
· android.permission.ACCESS_COARSE_LOCATION
android.permission-group.MICROPHONE
· android.permission.RECORD_AUDIO
android.permission-group.PHONE
· android.permission.READ_PHONE_STATE
· android.permission.CALL_PHONE
· android.permission.READ_CALL_LOG
· android.permission.WRITE_CALL_LOG
· com.android.voicemail.permission.ADD_VOICEMAIL
· android.permission.USE_SIP
· android.permission.PROCESS_OUTGOING_CALLS
android.permission-group.SENSORS
· android.permission.BODY_SENSORS
android.permission-group.SMS
· android.permission.SEND_SMS
· android.permission.RECEIVE_SMS
· android.permission.READ_SMS
· android.permission.RECEIVE_WAP_PUSH
· android.permission.RECEIVE_MMS
· android.permission.READ_CELL_BROADCASTS
android.permission-group.STORAGE
· android.permission.READ_EXTERNAL_STORAGE
· android.permission.WRITE_EXTERNAL_STORAGE
2. 动态权限申请流程



动态权限申请流程图如上:对于在运行时需要申请权限的方法,在执行前需要做一系列的权限申请操作。首先进行应用权限检查,检查应用是否有执行该方法所需要的权限,如有则可以正常运行,如没有则进行权限申请。进行权限申请时,首先会检查一下用户之前是否有响应过该权限的申请,如没有,则显示权限申请对话框,如有,则检查用户之前是否有勾选“不再提醒”的选项,如没有,显示权限申请对话框,如有,则进行应用无权限异常运行。显示权限对口框后,判断用户是否允许应用权限申请,如是,则进行应用有权限正常运行,如否,则进行应用无权限异常运行。
而代码实现则是:
-->1、使用Context.checkSelfPermission()接口先检查权限是否授权。
-->2、使用Activity.shouldShowRequestPermissionRationale()接口检查用户是否勾选不再提醒。
-->3、第2步返回为true时,表示用户并未勾选不再提醒选项,使用Activity.requestPermissions()接口向系统请求权限。
-->4、第2步返回为false时,表示用户已勾选不再提醒选项,则应用该弹框提示用户。
-->5、第3步执行后,不论用户是否授予权限,都会回调Activity.onRequestPermissionsResult()的函数。在Activity中重载onRequestPermissionsResult()函数,在接收授权结果,根据不同的授权结果做相应的处理。

3. 动态权限申请的适配方案
对于低于M版本的Android系统,没有动态权限的申请问题,动态权限的申请流程对于低于M版本的Android系统也不再适用。所以适配方案,首先要考虑低于M版本的Android系统,因此对于Android版本小于M版本时,在检查权限时,直接返回true就OK,直接屏蔽后续流程。
对于M版本的Android系统,动态权限的申请流程会产生好几个分支处理逻辑,这样不善于管理和维护。所以对于此处,为了将写得代码更加整洁和更易于维护,我们可以将动态权限申请进行一次封装,新建一个空白的activity用户权限申请和回调,然后在activity外包装一层管理内,限制一个调用的入口和出口,对于外部暴露唯一的入口和出口,这样对于外部逻辑代码需要调用权限时,将变得异常简单,并且由于将权限申请封装在了管理类中,对于低于M版本的Android系统也将没有任何引用,在管理类中直接对于低于M版本的权限申请请求直接回调全部已授权即可。
实际App中动态权限申请代码如下:
由于权限的动态申请与管理应该是伴随着整个App的生命周期的,所以PermissionsManager设计为单例的,且初始化保存着applicationContext作为默认跳转方式。
在App代码中,应在自定义的Application中调用PermissionsManager中的initContext()方法。



在App代码中,在需要申请权限的地方调用PermissionsManager中的newRequestPermissions()方法即可,不论Android版本是低于M版本还是高于M版本,根据实际App是否拥有对应权限,回调传入的该次权限申请的PermissionsResultsCallback接口的onRequestPermissionsResult()方法。这样就将动态权限的申请结果处理流程给唯一化,将权限的申请的入口和出口都唯一化。



这样将权限申请的细节和Android系统版本适配的细节都封装在了PermissionsManager内部,对于应用外部只需要知道申请权限的入口以及申请权限接口的出口即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: