在运行时请求权限

从Android 6.0(API级别23)开始,用户权限授予应用程序在应用程序运行时,当他们安装程序。这种方法简化了应用程序的安装过程,因为用户不需要安装或更新应用程序时授予权限。这也给了用户更多的控制应用程序的功能;例如,一个用户可以选择给相机应用程序访问相机而不是设备的位置。用户可以随时撤销权限,通过将应用程序的设置屏幕。

系统权限分为两类,普通和危险:

  • 正常的权限不直接用户的隐私风险。如果你的应用程序清单列出了一个正常的权限,系统自动授予许可。
  • 危险的权限可以给应用程序访问用户的机密数据。如果你的应用程序清单列出了一个正常的权限,系统自动授予许可。如果你列出一个危险的许可,用户必须显式地给应用程序审批。

在所有版本的Android系统,您的应用程序需要申报的正常和危险的权限需要在其应用程序清单,如声明中所述的权限。然而,宣言的影响是不同的根据系统版本和SDK应用程序的目标水平:

  • 如果设备运行Android 5.1或更低,或应用程序的目标SDK是22或更低:如果你在清单列表一个危险的许可,用户授予权限安装应用程序时,如果他们不授予权限,系统没有安装应用程序。
  • 如果设备运行Android 6.0或更高版本,和你的应用程序的目标SDK是23或更高:应用列表的权限清单,它必须要求每个危险的权限需要在应用程序运行时。用户可以授予或拒绝每一个权限,应用程序可以继续运行能力有限,即使用户拒绝权限请求。

注意:从Android 6.0(API级别23),用户可以在任何时候从任何应用程序撤销权限,即使应用程序API级别较低的目标。你应该测试你的应用程序,以确认它正确行为的时候丢失了一个需要许可,无论什么API级别应用程序的目标。

这节课描述了如何使用Android支持库检查,和请求,权限。Android 6.0的Android框架提供了类似的方法(API级别23)。然而,使用支持库比较简单,因为应用程序不需要检查哪个版本的Android上运行之前调用的方法。


检查权限

如果你的应用需要一个危险的许可,你必须检查你是否有权限每次执行一个操作,要求许可。用户总是可以撤销许可,所以即使相机昨天使用的应用程序,它不能假设它今天仍有该权限。

检查如果你有权限,调用ContextCompat.checkSelfPermission()方法。例如,这个代码片段展示了如何检查活动日历上写权限:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
        Manifest.permission.WRITE_CALENDAR);

如果应用程序许可,该方法返回PackageManager。PERMISSION_GRANTED,应用程序可以继续运行。如果应用程序没有许可,方法返回PERMISSION_DENIED,应用程序必须显式地要求用户许可。


请求的权限

如果你的应用需要一个应用程序清单中列出的危险的许可,它必须要求用户授予权限。Android提供了几种方法可用于请求许可。调用这些方法提出一个标准的Android对话框中,您不能定制。

解释为什么这个应用程序需要的权限

在某些情况下,您可能想要帮助用户理解为什么你的应用需要一个许可。摄影为例,如果一个用户启动一个应用程序,用户可能不会感到惊讶,允许应用程序要求使用相机,但是用户可能不理解为什么这个应用程序要访问用户的位置或联系人。在请求许可之前,你应该考虑为用户提供一个解释。记住,你不想淹没用户提供解释,如果你提供太多的解释,用户可能会发现应用令人沮丧和删除它。

您可以使用的一种方法是提供一个解释只有在用户已经拒绝了该权限的请求。如果用户一直试图使用功能需要一个许可,但一直拒绝许可的要求,这可能表明用户不理解为什么允许应用程序需要提供该功能。在这样的情况下,它可能是一个好主意给一个解释。

帮助找到的情况下,用户可能需要一个解释,Android提供了一种utiltity方法,shouldShowRequestPermissionRationale()。这个方法返回true,如果应用程序要求这个许可之前,用户拒绝请求。

注意:如果用户拒绝许可请求过去,再次选择了不要问选项允许请求系统对话框中,这个方法返回false。该方法还返回false如果设备政策禁止应用程序拥有该权限。

请求所需要的权限

如果应用程序已经不允许它的需求,应用程序必须调用一个requestPermissions()方法来请求适当的权限。应用程序通过它想要的权限,以及一个整数要求您指定识别这个许可请求的代码。这种方法异步函数:它返回,用户响应对话框之后,系统调用应用程序的回调方法对结果的影响,通过相同的请求代码,应用程序传递给requestPermissions()。

下面的代码检查应用程序允许读取用户的联系,必要时请求许可:

// 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.
    }
}

注意:当您的应用程序调用requestPermissions(),系统显示一个标准对话框给用户。应用程序不能配置或改变对话框。如果需要提供任何信息或向用户解释,你应该这样做之前你叫requestPermissions(),解释为什么所述应用程序需要的权限。

处理权限请求响应

当应用程序请求权限,系统向用户提供了一个对话框。当用户响应,系统调用应用程序的onRequestPermissionsResult()方法,传递用户响应。你的应用必须覆盖那个方法来找出是否被授予许可。回调传递相同的请求代码传递给requestPermissions()。例如,如果一个应用程序请求READ_CONTACTS访问它可能回调方法如下:

@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
    }
}

所示的对话框,系统描述了允许组织你的应用程序需要访问;它不特定的权限列表。举个例子,如果你请求READ_CONTACTS许可,该系统对话框只是说你的应用程序需要访问设备的联系人。一旦为每个用户只需要许可权限组。如果你的应用程序请求的任何其他权限组(应用程序清单中列出),系统自动赋予他们。请求许可时,系统调用你onRequestPermissionsResult()回调方法和通过PERMISSION_GRANTED,以同样的方式将如果用户有明确授予你的要求通过系统对话框。

注意:应用程序仍然需要每个许可需要显式地请求,即使用户已经允许另一个在同一组。此外,权限分组的分组可能改变未来的Android版本。你的代码不应该依赖于假设特定的权限或不在同一组。

例如,假设您在应用程序列表READ_CONTACTS和WRITE_CONTACTS清单。如果你请求READ_CONTACTS和用户授予权限,然后你请求WRITE_CONTACTS,系统立即授予许可没有与用户交互。

如果用户拒绝权限请求,应用程序应该采取适当的措施。例如,您的应用程序可能会显示一个对话框解释为什么它不能执行用户所请求的操作,需要许可。

当系统要求用户授予权限,用户可以选择告诉系统不要求许可了。在这种情况下,任何时候一个应用程序使用requestPermissions()要求权限,系统立即否认了这一请求。系统调用你onRequestPermissionsResult()回调方法和通过PERMISSION_DENIED,以同样的方式将如果用户已经明确拒绝了你的请求。这意味着当你叫requestPermissions(),你不能假设任何直接与用户交互。

Android 6.0 运行时权限处理的更多相关文章

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

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

  2. Android数据存储之Android 6.0运行时权限下文件存储的思考

    前言: 在我们做App开发的过程中基本上都会用到文件存储,所以文件存储对于我们来说是相当熟悉了,不过自从Android 6.0发布之后,基于运行时权限机制访问外置sdcard是需要动态申请权限,所以以 ...

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

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

  4. android-详解Android 6.0运行时权限

    感谢郭神,从Android 6.0开始,不再是安装应用时用户确定获得全部的权限.而是在使用软件过程中需要该权限时,弹出对话框让用户选择权限.不仅如此,用户选择权限后还可以关闭. 检查是否获得权限 通过 ...

  5. Android 6.0运行时权限

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

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

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

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

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

  8. Android M Permission 运行时权限 学习笔记

    Android M Permission 运行时权限 学习笔记 从Android 6.0开始, 用户需要在运行时请求权限, 本文对运行时权限的申请和处理进行介绍, 并讨论了使用运行时权限时新老版本的一 ...

  9. Android M以上运行时权限(Google官方出品)

    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6690152.html 网上运行时权限的例子.Demo无计其数,但是和Google官方出品的比起来,都显得很 ...

随机推荐

  1. GIT笔记命令行(1)

    Git简单易用,只要输入git就可以列出他的所有参数 C:\Users\spu>git usage: git [--version] [--help] [-C <path>] [-c ...

  2. HTML基础篇之HTML基本元素

    <h1>标题一</h1> <h2>标题二</h2> <h3>标题三</h3> <h4>标题四</h4> ...

  3. 未找到导入的项目,请确认 &lt;Import&gt; 声明中的路径正确

    当使用vs出现下列情况: D:\xxxx\Web\Web.csproj : error  : 无法读取项目文件“Web.csproj”. D:\xxxx\WebServiceManager\Web\W ...

  4. View加载过程

    1. 先判断子类是否重写了loadView,如果有直接调用.之后调viewDidLoad完成View的加载.2 .如果是外部通过调用initWithNibName:bundle指定nib文件名的话,V ...

  5. Java Struts2 POI创建Excel文件并实现文件下载

    Java Struts2 POI创建Excel文件并实现文件下载2013-09-04 18:53 6059人阅读 评论(1) 收藏 举报 分类: Java EE(49) Struts(6) 版权声明: ...

  6. 51nod 1040最大公约数和(欧拉函数)

    1040 最大公约数之和 题目来源: rihkddd 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 给出一个n,求1-n这n个数,同n的最大公约数 ...

  7. 如何查看crontab的日志记录

    在Unix和类Unix的操作系统之中,crontab命令常用于设置周期性被执行的指令,也可以理解为设置定时任务. crontab中的定时任务有时候没有成功执行,什么原因呢?这时就需要去日志里去分析一下 ...

  8. SQL索引学习-索引结构

    前一阵无意中和同事讨论过一个SQL相关的题(通过一个小问题来学习SQL关联查询),很惭愧一个非常简单的问题由于种种原因居然没有回答正确,数据库知识方面我算不上技术好,谈起SQL知识的学习我得益于200 ...

  9. linux+jre+apache+mysql+tomcat调优

    一.不再为Apache进程淤积.耗尽内存而困扰 0. /etc/my.cnf,在mysqld那一段加上如下一行: log-slow-queries=queries-slow.log 重启MySQL 酌 ...

  10. java个人总结

    20145230<Java程序设计>课程总结 每周读书笔记链接汇总 20145230<java程序设计>第0周学习总结:http://www.cnblogs.com/kobe2 ...