1. 在Android6.0以上才需要在运行时请求权限,在旧Android版本上保留原有逻辑,安装时授予权限。
  2. 用旧版本sdk编译的apk,都使用旧版本权限方式,安装时授予权限。(也就是说:兼容旧版本)
  3. 用Android6.0(targetSdkVersion 23)作为目标版本才需要处理新的权限问题。
  4. 还有一个蛋疼的问题:程序运行当中,用户关闭了权限,会发生什么?(大面积的崩溃)

1.  API 23 权限分类

1.1.基本权限(安装时授权的一类基本权限)

只需要在AndroidManifest.xml中简单声明这些权限就好,安装时就授权。不需要每次使用时都检查权限,而且用户不能取消以上授权,如:(表1-1)。

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS

访问定位额外命令

android.permission.ACCESS_NETWORK_STATE

获取网络状态

android.permission.ACCESS_NOTIFICATION_POLICY

 

android.permission.ACCESS_WIFI_STATE

获取WiFi状态

android.permission.ACCESS_WIMAX_STATE

 

android.permission.BLUETOOTH

使用蓝牙

android.permission.BLUETOOTH_ADMIN

蓝牙管理

android.permission.BROADCAST_STICKY

连续广播

android.permission.CHANGE_NETWORK_STATE

改变网络状态

android.permission.CHANGE_WIFI_MULTICAST_STATE

改变WiFi多播状态

android.permission.CHANGE_WIFI_STATE

改变WiFi状态

android.permission.CHANGE_WIMAX_STATE

 

android.permission.DISABLE_KEYGUARD

允许程序禁用键盘锁

android.permission.EXPAND_STATUS_BAR

允许程序扩展或收缩状态栏

android.permission.FLASHLIGHT

允许访问闪光灯

android.permission.GET_ACCOUNTS

访问GMail账户列表

android.permission.GET_PACKAGE_SIZE

获取应用的文件大小

android.permission.INTERNET

访问网络连接,可能产生GPRS流量

android.permission.KILL_BACKGROUND_PROCESSES

允许程序调用killBackgroundProcesses(String).方法结束后台进程

android.permission.MODIFY_AUDIO_SETTINGS

修改声音设置信息

android.permission.NFC

允许程序执行NFC近距离通讯操作,用于移动支持

android.permission.READ_SYNC_SETTINGS

读取同步设置,读取Google在线同步设置

android.permission.READ_SYNC_STATS

读取同步状态,获得Google在线同步状态

android.permission.RECEIVE_BOOT_COMPLETED

允许程序开机自动运行

android.permission.REORDER_TASKS

重新排序系统Z轴运行中的任务

android.permission.REQUEST_INSTALL_PACKAGES

 

android.permission.SET_TIME_ZONE

设置系统时区

android.permission.SET_WALLPAPER

设置壁纸建议

android.permission.SET_WALLPAPER_HINTS

 

android.permission.SUBSCRIBED_FEEDS_READ

访问订阅内容

android.permission.TRANSMIT_IR

 

android.permission.USE_FINGERPRINT

 

android.permission.VIBRATE

使用振动

android.permission.WAKE_LOCK

唤醒锁定

 

 

表1-1(基本权限表)

1.2.新运行时权限

以下权限(表1-2)(android 6.0系统及以上)需要在代码内询问是否授权,如果不询问授权,可能会导致app就崩溃;

权限进行了分组,同一组的任何一个权限被授权了,其他权限也自动被授权例如,一旦WRITE_CONTACTS被授权了,app也有READ_CONTACTS和GET_ACCOUNTS了。 

android 系统权限授权 安卓授权管理_android 6.0

表 1-2(运行时权限)

Ps:

Android N预览版 权限上的一些改变

2.  API 23以上权限开发

2.1.思路大体如下(图2-1)

如果用户系统内带有的权限控制工具(如 360安全卫士)默认所有授权都不会被提醒,那么我们为某个权限请求requestPermissions时,授权对话框就不会被弹出来,结果就是,app啥也不干。用户体验会非常糟糕。所以 判断一下是否‘不再提醒’:

android 系统权限授权 安卓授权管理_运行时权限_02

图 2-1(权限开发流程图)

 

2.2.原生代码实现方式

2.2.1.  Void()

1.  检查权限:checkSelfPermission(Stringpermission);

2.  请求权限:requestPermissions(String permission);

3.  检查是否需要展示请求权限:shouldShowRequestPermissionRationale(Stringpermission);

4.  回调:onRequestPermissionsResult;

第一步:像以前一样在AndroidManifest.xml添加声明权限;

第二步:Code 2-2 (授权逻辑); 

android 系统权限授权 安卓授权管理_权限_03

Code 2-2 (授权逻辑)

 

第三步:Code 2-3(回调逻辑);

 

android 系统权限授权 安卓授权管理_android 6.0_04

                                                                                      Code 2-3(回调逻辑) 

2.3. v4兼容库实现

2.3.1.  Void()

Activity :

1.  检查权限:ContextCompat.checkSelfPermission()

2.       ActivityCompat.requestPermissions()这个方法在M之前版本调用,OnRequestPermissionsResultCallback直接被调用,带着正确的PERMISSION_GRANTED或者PERMISSION_DENIED。

3.        ActivityCompat.shouldShowRequestPermissionRationale()在M之前版本调用,永远返回false。用v4包的这三方法,完美兼容所有版本!这个方法需要额外的参数,Context or Activity。别的就没啥特别的了。下面是代码:

Fragment:
4.        FragmentCompat.requestPermissions();
5.        FragmentCompat.shouldShowRequestPermissionRationale();

2.3.2. Code




android 系统权限授权 安卓授权管理_android 6.0_05





2.4. 第三方兼容库实现


Karumi’s Dexter是我目前在用的第三方库,github地址:https://github.com/Karumi/Dexter ;

使用该第三方库,代码比较简便就能实现很好的用户体验。

我们只需要考虑 在用户功能的实现。我们都不需要去花时间编写 判断有无权限、判断是否勾选了‘不再提醒’… 这一类流程几乎是固定的逻辑。

2.4.1.  代码逻辑流程

思路流程图(图 2-1)和代码逻辑流程(图2-2):



android 系统权限授权 安卓授权管理_android 系统权限授权_06



图 2-2(代码逻辑)

2.4.2.  Void()


1.         Dexter.checkPermission(…);//检查权限
2.         PermissionToken. continuePermissionRequest();//打开授权框;
PermissionListener  //单个授权监听类
1.        PermissionListener.onPermissionGranted(PermissionGrantedResponseresponse);有授权情况下调用;
2.        PermissionListener.onPermissionDenied(PermissionDeniedResponseresponse);非授权情况下调用;
3.        PermissionListener.onPermissionRationaleShouldBeShown(PermissionRequestpermission,PermissionToken token);
MultiplePermissionsListener//多个授权监听
1.        MultiplePermissionsListener.onPermissionRationaleShouldBeShown(List<PermissionRequest>permissions, PermissionToken token);无授权&&非第一次授权&&非勾选“不再提醒”情况下调用;
2.        MultiplePermissionsListener.onPermissionsChecked(MultiplePermissionsReportreport) {   for (PermissionGrantedResponseresponse : report.getGrantedPermissionResponses()) {    //       有授权的权限    }    for (PermissionDeniedResponseresponse : report.getDeniedPermissionResponses()) {        //      无授权的权限    }}


2.4.3.Code

2.4.3.1.     Application: 



android 系统权限授权 安卓授权管理_运行时权限_07



2.4.3.2.   Activity/Fragment:



android 系统权限授权 安卓授权管理_android 系统权限授权_08



3.   参考文献

[1]  http://jijiaxin89.com/2015/08/30/Android-s-Runtime-Permission/ ,2015.