前言

 谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6.0出来,使得用户权限授权变得合理。这可能也是参考IOS系统的,只有在用户需要使用权限的时候,才去授权请求,这样做的目的是提高用户体验,当然,用户感觉好了,受苦的是我们开发人员,原来的规则不适用了,现在我们去适应新的规则,毕竟是靠谷歌这颗大树吃饭的嘛。

原来权限模型

 在Android 6.0版本之前,权限都是一条龙服务的,只要用户安装完,AndroidManifest清单上申请的权限都会被系统默认授权,并且授权后也撤销不了。这样的弊端在哪里呢?有些权限可能用户觉得不需要,比如他不想有通知的权限,不想受到通知的干扰,那么他就不能屏蔽通知,就是不需要的权限,他去不掉,自主权不在他那边。还有一些情况是,一些恶意程序,会利用这个权限默认授权,进行恶意获取用户数据和攻击。所以Android 6.0版本,一方面让用户更加容易的控制自己的隐私,一方面需要重新适配应用权限。

Android 6.0权限模型

采用新的权限模型,只有在需要权限的时候,才告知用户是否授权,是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候,需要先检查是否有所需要的权限申请。这样的用户的自主性提高很多,比如用户可以给APP赋予摄像的权限,但是可以拒绝记录设备位置的权限,就是怕位置信息上传等等。

权限流程

在API 23中,权限满足的标准流程:

但这里有个问题,那就是在系统授权弹窗环节,提醒框会有个不再提示的复选框,如果用户点击不太提示,并拒绝授权,那么再下次授权的时候,系统授权弹窗的提示框就不会在提示,所以我们很有必要需要自定义权限弹窗提示框,那么流程图就变成如下了。

权限类型

 在图中,我们可以看到整个权限里,可以分为系统权限和特殊权限授权。系统权限中,又分为normal和dangerous类型。
 normal:这个权限类型并不直接威胁到用户的隐私,可以直接在manifest清单里注册,系统会帮我们默认授权的。
 dangerous:这个可以直接给app访问用户一些敏感的数据,不仅需要在manifest清单里注册,同时在使用的时候,需要向系统请求授权。
 值得注意一点,这里有特殊权限授权的区别,分别是SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS,虽然这两个权限也是属于dangerous权限类型,但是这两个授权请求方式和其他dangerous权限是不一样的,需要特殊处理 。
dangerous列表:
 
Permission Group Permissions
CALENDAR
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE

版本兼容

 当然,谷歌也是考虑到如果是以API 23之前的版本编译的APP,在6.0的系统上运行,还是能兼容的。如果是23之前的版本编译的APP,则权限模型走的是老的模式,也就是在一条龙的模式,在manifest清单注册,系统会帮我们默认授权,并且也能运行。
   但如果是以API 23的版本编译的APP,那走的的必须是新的权限模型,在遇到dangerous权限的时候,必须进行授权的,如果没有进行授权话,系统则会提示崩溃信息。所以,基于6.0系统的开发的程序, 在打开页面的时候,必须要考虑这个页面是否用到需要授权的权限,页面检测是否已经授权过了没。
 
实现方式
   第一步:检测权限
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);
    第二步:请求权限
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) { // Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) { // Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission. } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS); // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
 第三步:处理权限请求结果
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the
// contacts-related task you need to do. } else { // permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
} // other 'case' lines to check for other
// permissions this app might request
}
}
其中要特别注意的是,如果是针对

“android.permission.SYSTEM_ALERT_WINDOW”
“android.permission.WRITE_SETTINGS”

这两个权限,实现方式跟上之前在工作中,碰到一种情况,如果是运行在6.0的版本上是需要走新的权限模型,如果是运行在老的版本上,则需要进行一个判断,此时碰到一个问题是,在谷歌官方推荐中,在判断app运行的系统是否在Android M上时,它的判断是如下:  Build.VERSION.CODENAME.equals("MNC"); 可是在我实际适配中,发现这句却无效的,就改用Build.VERSION.SDK_INT >= 23。的,需要另外特殊处理。

针对SYSTEM_ALERT_WINDOW权限,需要向系统发送一个ACTION_MANAGE_OVERLAY_PERMISSION.这样一个动作,同时可以用Settings.canDrawOverlays() 方法进行判断之前是否已经授权过了。
针对WRITE_SETTINGS权限,需要向系统发送一个ACTION_MANAGE_WRITE_SETTINGS 这样一个动作,同时可以用Settings.System.canWrite().方法进行判断之前是否已经授权过了。
具体代码:
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

注意点

 之前在工作中,碰到一种情况,如果是运行在6.0的版本上是需要走新的权限模型,如果是运行在老的版本上,则需要进行一个判断,此时碰到一个问题是,在谷歌官方推荐中,在判断app运行的系统是否在Android M上时,它的判断是如下:  Build.VERSION.CODENAME.equals("MNC"); 可是在我实际适配中,发现这句却无效的,就改用Build.VERSION.SDK_INT >= 23。

总结

  1. 首先要知道6.0版本权限模型跟原来版本是不同的,不再是统一在manifest中默认系统授权,而是有需要的时候,向系统请求授权,提高用户体验。
  2. 了解权限检测流程,一点注意点是如果系统权限弹窗提示框被不再提醒了,需要我们自定义提示弹窗,引导用户去授权。
  3. 明白权限类型,分为normal和dangerous类型,同时,在dangerous中还需要注意一点,SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS这两个特殊授权请求方式,跟一般授权请求方式不同。
  4. 在判断APP是否运行在Android M上,可以用版本号来判断,可以准确点。

原文出自:http://www.cnblogs.com/cr330326/p/5181283.html

android 6.0(23)的权限管理的更多相关文章

  1. Android权限管理之Android 6.0运行时权限及解决办法

    前言: 今天还是围绕着最近面试的一个热门话题Android 6.0权限适配来总结学习,其实Android 6.0权限适配我们公司是在今年5月份才开始做,算是比较晚的吧,不过现在Android 6.0以 ...

  2. (补漏)Springboot2.0 集成shiro权限管理

    原文Springboot2.0 集成shiro权限管理 一.关于停止使用外键. 原本集成shiro建立用户.角色.权限表的时候使用了外键,系统自动创建其中两个关联表,用@JoinTable.看起来省事 ...

  3. Android6.0运行时权限管理

    自从Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifest设置就可以任意获取权限,而是更加的注重用户的隐私和体验,不会再强迫用户因拒绝不该拥有的权限而导致的无法安装 ...

  4. Android 6.0 运行时权限处理完全解析

    一.概述 随着Android 6.0发布以及普及,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化.对于6.0的几个主要的变化,查看查看官网的这篇文章http:// ...

  5. 谈谈Android 6.0运行时权限理解

    前言 谷歌在2015年8月份时候,发布了Android 6.0版本,代号叫做“棉花糖”(Marshmallow ),其中的很大的一部分变化,是在用户权限授权上,或许是感觉之前默认授权的不合理,现在6. ...

  6. Android 6.0 运行时权限处理

    在运行时请求权限 从Android 6.0(API级别23)开始,用户权限授予应用程序在应用程序运行时,当他们安装程序.这种方法简化了应用程序的安装过程,因为用户不需要安装或更新应用程序时授予权限.这 ...

  7. Android 6.0运行时权限

    一.Runtime Permissions Android 6.0在手机安全方面做的一个处理就是增加了运行时权限(Runtime Permissions). 新的权限机制更好的保护了用户的隐私,Goo ...

  8. Android 6.0 运行时权限处理问题

    序 自从升级到Android M以来,最大的改变就是增加了运行时权限RuntimePermission,6.0以上的系统如果没有做适配,运行了targetSDK=23的App时就会报权限错误.我们知道 ...

  9. Android : M 与 N 的权限管理

    从 M 开始,permission 分为 Normal permission Runtime permission Normal permission 直接在 manifest 里声明就可以用了. a ...

随机推荐

  1. 洛谷 P1854 花店橱窗布置

    题目描述 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定的,从左到右按1到V顺序编号,V是花瓶的数目.花束可以移动,并且每束花用1到F的整数标识 ...

  2. centos7 showdoc 手动安装部署

    1.从 https://github.com/star7th/showdoc 下载压缩包: 2.解压文件,然后将showdoc-master下面的文件上传至服务器对应的文件下面: 3.在浏览器中输入 ...

  3. Directx 9 VS2015环境搭建

    安装好Directx9 sdk和vs2015后 打开vs,新建项目 --> c++项目  -->win32控制台应用程序-->空项目 创建项目后,右键项目属性, 包含目录 D:\Pr ...

  4. Excel分类汇总

    版本:2016,数据来源:我要自学网,曾贤志老师 1.首先,要进行分类,在进行汇总, 如对日期进行汇总的话:​   如果对品名进行汇总的话   ​2.光标要定在数据源,在选择分类字段(包含项目比如品名 ...

  5. get方法传递中文数据的时候如何进行转码

    首先,如果是在js端的代码,用window.href进行请求时,需要进行转码 前台jsp中: var param = document.getElementById('param').value;pa ...

  6. Django基础(三)

    Template 不能直接将html硬编码到视图里的原因: 对页面设计进行的任何改变都必须对python 代码进行相应的修改.站点设计的修改往往比底层python 代码的修改要频繁的多,因此如果可以在 ...

  7. python web框架 Django基本操作

    django 操作总结! django框架安装: cmd安装: pip3 install django pycharm安装: 在python变量下 搜索 django 安装 创建django项目: c ...

  8. [Codeforces]#179 div1-----295ABCDE

    摘自我的github:https://github.com/Anoxxx The Solution Source: Codeforces Round #179 (Div. 1) VJudge链接: h ...

  9. HDLM命令dlnkmgr详解之二__help/clear

    1.help操作 主要显示命令的帮助信息. 显示所有操作的帮助信息 -bash-3.2# dlnkmgr help dlnkmgr: Format dlnkmgr { clear | help | o ...

  10. Hbase优化记录

    <configuration><property><name>hbase.rootdir</name><value>hdfs://gagcl ...