在运行时请求权限

从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. 跟我一起学习VIM

    跟我一起学习VIM - The Life Changing Editor   前两天同事让我在小组内部分享一下VIM,于是我花了一点时间写了个简短的教程.虽然准备有限,但分享过程中大家大多带着一种惊叹 ...

  2. Cen0S下挂载设备

    在CentOS中,如果我们要查看光驱,U盘或者要把安装包挂载到某个文件夹,我写下我的一些理解. 所谓的挂载,就是把物理设备或者文件(包含安装文件,压缩包等等),与系统中的某个目录建立一个快捷方式,然后 ...

  3. Hadoop安装——如何修改端口冲突

    在一个集群中,尽管是多用户,但是端口是公用的,存在冲突的可能.如果另一个用户已经采用默认配置安装了hadoop,那么当前用户再安装hadoop时,必然会产生端口的冲突.在配置自己的hadoop时,可以 ...

  4. PHP 对于 MYSQL 基础操作

    基础 <?php // 不打印 notice info // error_reporting(0); // 连接 mysql $con = mysql_connect("localho ...

  5. 在ubuntu上搭建开发环境4---ubuntu简单的搭建LAMP环境和配置

    最近重新安装了Ubuntu,但是之前的LAMP环境自然也就没有了,实在是不想再去编译搭建LAMP环境(这种方法实在是太费时间,而且太容易遇到各种不知道为什么的错误),所以,就去查查有没有什么简单的搭建 ...

  6. C语言常用知识

    跳出for循环主要有以下2中方式: 1.用break语句.如: int i; for(i=0; i<10; i++) {     if(i>3)    // 如果i>3,跳出for循 ...

  7. Html5_禁止Html5在手机上屏幕页面缩放

    最近测试html5页面,发现默认都允许用户缩放页面,或者在屏幕双击放大或缩小.即相当于这样设置 <meta name="viewport" content="wid ...

  8. ubunut 14.04 将Caps Lock设置为Control

    入手了emacs,一直折腾想把caps Lock设置为control键. 网上看到一个用gnome里找到系统-首选项之类可以直接设置的.在14.04版的ub中是找不到的(新版设置太坑,只有那么几个选项 ...

  9. 搜索结果高亮显示(不改变html标签)

      分类: 代码2010-02-28 13:44 1574人阅读 评论(3) 收藏 举报 htmlinputstring 一.问题的产生 搜索结果高亮显示,在新闻标题,来源之类的地方好做,只需要用st ...

  10. Dictionary(HashMap)的实现

    什么是哈希表? 哈希表(Hash table,也叫散列表),是根据key而直接进行访问的数据结构.也就是说,它通过把key映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放 ...