前言

 谷歌在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权限是不一样的,需要特殊处理 。
normal列表:
  • ACCESS_LOCATION_EXTRA_COMMANDS
  • ACCESS_NETWORK_STATE
  • ACCESS_NOTIFICATION_POLICY
  • ACCESS_WIFI_STATE
  • BLUETOOTH
  • BLUETOOTH_ADMIN
  • BROADCAST_STICKY
  • CHANGE_NETWORK_STATE
  • CHANGE_WIFI_MULTICAST_STATE
  • CHANGE_WIFI_STATE
  • DISABLE_KEYGUARD
  • EXPAND_STATUS_BAR
  • GET_PACKAGE_SIZE
  • INTERNET
  • KILL_BACKGROUND_PROCESSES
  • MODIFY_AUDIO_SETTINGS
  • NFC
  • READ_SYNC_SETTINGS
  • READ_SYNC_STATS
  • RECEIVE_BOOT_COMPLETED
  • REORDER_TASKS
  • REQUEST_INSTALL_PACKAGES
  • SET_TIME_ZONE
  • SET_WALLPAPER
  • SET_WALLPAPER_HINTS
  • TRANSMIT_IR
  • USE_FINGERPRINT
  • VIBRATE
  • WAKE_LOCK
  • WRITE_SYNC_SETTINGS
  • SET_ALARM
  • INSTALL_SHORTCUT
  • UNINSTALL_SHORTCUT
 

dangerous列表:
Permission Group Permissions
CALENDAR
  • READ_CALENDAR
  • WRITE_CALENDAR
CAMERA
  • CAMERA
CONTACTS
  • READ_CONTACTS
  • WRITE_CONTACTS
  • GET_ACCOUNTS
LOCATION
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION
MICROPHONE
  • RECORD_AUDIO
PHONE
  • READ_PHONE_STATE
  • CALL_PHONE
  • READ_CALL_LOG
  • WRITE_CALL_LOG
  • ADD_VOICEMAIL
  • USE_SIP
  • PROCESS_OUTGOING_CALLS
SENSORS
  • BODY_SENSORS
SMS
  • SEND_SMS
  • RECEIVE_SMS
  • READ_SMS
  • RECEIVE_WAP_PUSH
  • RECEIVE_MMS
STORAGE
  • READ_EXTERNAL_STORAGE
  • WRITE_EXTERNAL_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上,可以用版本号来判断,可以准确点。

Android6.0权限相关推荐

  1. Android6 0权限机制(一):介绍

    本篇文章已授权微信公众号 hongyangAndroid (鸿洋)独家发布 Android6.0权限机制(一):介绍 Android6.0权限机制(二):封装 Android6.0权限机制(三):6. ...

  2. Android6.0权限适配及兼容库的实现

    从6.0 MarshMallow开始,Android支持动态权限管理,即有些权限需要在使用到的时候动态申请,根据用户的选择需要有不同的处理,具体表现可以看下图: 本文并不关心权限适配的原理,原理可以参 ...

  3. android 6.0 短信权限,Android6.0权限适配

    Code4Android .jpg 前言 现在谈论Android权限适配可能有点没必要,因为网上关于权限适配的文章很多,搜一下Android6.0权限适配关键词能搜到一堆文章,而且很多写的还很不错.不 ...

  4. android拍照所需的权限,eclipse --- Android拍照,相册选择图片以及Android6.0权限管理...

    [实例简介] eclipse --- Android拍照,相册选择图片以及Android6.0权限管理 [实例截图] [核心代码] camreainandroidm └── camreainandro ...

  5. Android6.0权限大全和权限分类

    自从出了Android6.0权限管理之后,再也不能像以前那样粘贴复制了,必须认识权限了,所以总结一下方便以后自己使用. 一.所有权限 访问登记属性 android.permission.ACCESS_ ...

  6. Android打电话功能权限报错,从打电话权限报错看Android6.0权限变化

    引言:去年Android 6.0发布后,其新引入的(Requesting Permissions at Run Time)运行时权限就备受开发者关注,随着今年国内手机厂商对6.0系统的普及,觉得大家有 ...

  7. android6.0权限管理工具EasyPermissionUtil

    前言 android6.0開始,权限的申请发生了改变,申请变的动态化,也就是执行时权限,和iOS相仿,动态化的意思是指,在每次使用须要危急权限的方法的时候.须要检查程序是否获得了该权限的许可.动态化的 ...

  8. Android教程 -05 Android6.0权限的管理

    视频为本篇博客知识的讲解,建议采用超清模式观看, 欢迎点击订阅我的优酷 height="498" width="510" src="http://pl ...

  9. android关闭权限管理,Android6.0权限管理以及使用权限该注意的地方

    Android 6.0 Marshmallow首次增加了执行时权限管理,这对用户来说,能够更好的了解.控 制 app 涉及到的权限.然而对开发人员来说却是一件比較蛋疼的事情.须要兼容适配,并保证程序功 ...

最新文章

  1. jstl sql标签使用
  2. 《C++ Primer》7.1.4节练习
  3. 与kylin_Kylin 迁移到 HBase 实践在小米的实践
  4. PostGIS mysql_fdw安装(Linux)
  5. oracle存储过程(带参数的存储过程)
  6. Window Operations
  7. ESP-AT SSL 单向认证指令操作以及问题分析
  8. 需求文档你怎么写?为什么这么写?如何写一份好的需求文档?
  9. Fiddler-本机抓包模拟器
  10. 盘盘在项目中你常用的那些数组API
  11. 将linux系统移动硬盘,着手打造你的随身系统---将linux装进移动硬盘
  12. 在局域网内怎样使两台计算机共享,怎么使两台电脑共享数据?
  13. 工作日志,常见的统计解决方案
  14. [OpenCV] 练习题实现代码 使用 cv.addWeighted 函数在文件夹中创建图像的幻灯片放映,并在图像之间进行平滑过渡
  15. 中国移动MAS业务技术培训
  16. 为什么我们说“买东西”,而不说“买南北”?
  17. 腾讯QQ修改密保手机
  18. Unity MVC框架之见解
  19. Linux性能排查——CPU软中断问题
  20. 工商管理管理学知识归纳

热门文章

  1. 计算机系统软件和应用软件的区别
  2. 家装家居自救指南:线上线下大融合
  3. 统计图表之桑基图 sankey diagram
  4. c++ 不要节约代码行数_不要只是代码,但也c
  5. android 取消蓝牙配对框 实现自动配对 输入PIN码
  6. Apache的Order Allow,Deny 配置详解
  7. 国内 Mono 相关文章汇总
  8. 树状数组及线段树入门(SDNU1665-1668)
  9. JAVA计算机毕业设计喜枫日料店自助点餐系统(附源码、数据库)
  10. TM4C123GXL_PWM