Android 6.0开始动态请求权限

翻译 2016年05月10日 21:41:01

转载请注明来源: http://blog.csdn.net/kjunchen/article/details/51366845

动态请求权限

从Android 6.0(API 23)开始,允许用户在应用运行时决定是否允许权限,而不是在应用安装的时候。这种方法简化了应用的安装过程,因为用户在安装或更新应用的时候不需要允许权限。他也让用户对应用的功能有更多的控制;例如,用户可以选择给予相机应用相机的权限但是不允许使用设备位置的权限。用户可进入应用设置随时撤销权限。

系统权限被分为两种类型,正常的(normal)和敏感的(dangerous):

  • 正常的权限不会直接让用户的隐私处于危险中。如果你的应用在清单文件中列入了正常的权限,系统会自动允许这些权限。

  • 敏感权限给予应用方位用户的机密数据。如果你的应用在清单文件中列入危险类权限,会明确地让用户对你的应用允许权限。

更多信息请看 Normal and Dangerous Permissions.

在所有的Android版本中,你的应用需要在清单文件中去申明它需要的正常的和危险的权限。然而,声明的影响是不同的,依赖于系统版本和你应用的目标SDK等级:

  • 如果设备运行在Android 5.1或更低,或者你的应用的 target SDK是22或者更低;如果你在清单文件中加入了敏感权限,当他们在安装应用的时候必须同意权限;如果他们不同意权限,系统则不会安装应用。

  • 如果设备运行在Android 6.0或更高的版本,或者你的应用的 target SDK是23或者更高。应用必须在manifest文件中加入权限,而且在应用运行过程中必须在它需要的时候请求每一个危险的权限。用户可以允许或者拒绝每一个权限,即使用户拒绝了一个权限的请求而应用可以在限制功能地继续运行。

注意: 从Android6.0(API 23)开始,用户可以在任何时候撤销任何应用的权限,即使应用目标SDK低于23。你应该测试你的用用验证它正常的表现当它缺少需要的权限,不管你的应用的target SDK等级是多少。

检查权限

如果你的应用需要一个敏感权限,你必须检查是否具有权限当你每次执行一个操作需要一个权限时。用户总是可以自由地撤销权限,所以,即使应用昨天使用了相机,但是今天可能没有相机权限。

为了检查你是否有该权限,调用 ContextCompat.checkSelfPermission()方法。例如,下面片段展示了如何检查一个Activity是否具有日历权限:

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

如果一个用拥有权限,这个方法会返回 PackageManager.PERMISSION_GRANTED ,应用可以继续进行操作。如果应用没有权限,方法会返回 PERMISSION_DENIED ,应用必须去想用户请求该权限。

请求权限

如果你的应用需要一个敏感权限加入到manifest文件中,他必须征求用户允许权限。Android提供了一些方法让你可以去请求一个权限。调用这些方法会弹出一个标准的Android弹出框,你不能自定义。

解释你的应用为什么需要权限

在某些情况中,你可能想要帮助用户理解你的应用个为什么需要一个权限。例如,如果一个用户运行一个相机应用,应用请求使用相机权限,用户对此并不会感到惊奇,但是,用户并不理解为什么应用想要访问用户的位置或者联系人。在你请求一个权限之前,你应该考虑向用户提供一个解释。记住,如果你不想用解释说服用户;如果你提供太多的解释,用户可能发现应用令他沮丧并卸载它。

如果用户已经关闭了权限请求,你可能需要提供一个解释。如果用户坚持尝试使用一个功能但需要请求一个权限,但总是关闭权限请求,可能说明用户没有理解应用为什么需要该功能这个权限。在这种情况下,去展示一个解释可能是一个好主意。

为了帮助这种情况,用户可能需要一个解释,Android提供了一个实用的方法,shouldShowRequestPermissionRationale() 。如果应用以前请求过这个权限并且被用户拒绝了那么这个方法会返回 true

注意: 如果用户在权限请求系统弹出框关闭权限请求而且选择不在提示,这个方法返回 false 。如果一个设备已经禁止了应用的那个权限这个方法也会返回 false

请求你需要的权限

如果你的应用没有你需要的权限,你必须调用 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版本中群组的权限分组可能会有改变。你的代码不应该依赖特定的权限是不是在一个组里。

例如,假设你应用的manifest文件中既有 READ_CONTACTS 权限又有 WRITE_CONTACTS 权限。如果你请求 READ_CONTACTS 并且用户允许了改权限,然后你请求 WRITE_CONTACTS ,系统会立即允许权限而不和用户交互。

如果用户拒绝一个权限请求,你的应用应该采取适当的处理。例如,你的应用可能展示一个对话框,解释它为什么需要权限去执行用户请求的操作。

当系统询问用户允许权限时,用户可以有选择的告诉系统不用在此询问权限。在这种情况下,任何时候,应用使用 requestPermissions() 方法去在次请求权限时,系统会立即拒绝请求。如果用户已经明确的拒绝了你的请求,系统会调用 onRequestPermissionsResult() 方法并且通过PERMISSION_DENIED 。这意味着当你调用 requestPermissions() 方法时,你不能在用户操作的地方产生预期的效果。

正常权限(Normal Permissions)

在API 23中,下面权限被定义为正常权限

  • 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
  • INSTALL_SHORTCUT
  • INTERNET
  • KILL_BACKGROUND_PROCESSES
  • MODIFY_AUDIO_SETTINGS
  • NFC
  • READ_SYNC_SETTINGS
  • READ_SYNC_STATS
  • RECEIVE_BOOT_COMPLETED
  • REORDER_TASKS
  • REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
  • REQUEST_INSTALL_PACKAGES
  • SET_ALARM
  • SET_TIME_ZONE
  • SET_WALLPAPER
  • SET_WALLPAPER_HINTS
  • TRANSMIT_IR
  • UNINSTALL_SHORTCUT
  • USE_FINGERPRINT
  • VIBRATE
  • WAKE_LOCK
  • WRITE_SYNC_SETTINGS

敏感权限(Dangerous permissions)

Permission Group Permissions
CALENDAR READ_CALENDARWRITE_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

原文链接

鄙人英语能力有限,翻译难免有误,请读者多多包含! 也欢迎指正。

欢迎加QQ群交流: 365532949
Homepage: http://junkchen.com

相关文章推荐

Android 6.0 动态权限申请

Android 6.0 (API 23) 之前应用的权限在安装时全部授予,运行时应用不再需要询问用户。在 Android 6.0 或更高版本对权限进行了分类,对某些涉及到用户隐私的权限可在运行时根据用...

android 实现兼容6.0与5.0动态请求权限

最近在写直播类应用,需要实现再打开直播前预览界面前首先判断应用是否拥有照相的权限。android自从更新到6.0之后应用的某些敏感权限变成了动态请求权限 (Dangerous permissio...

Android 6.0在运行时申请权限解释与实例

Android 6.0在运行时申请权限从android 6.0(API23)开始,当app运行时用户授予用户的权限,而不是在安装程序的时候。系统权限分为2种,分别为normal和dangerus. N...

【android的logcat详细用法】

Android日志系统提供了记录和查看系统调试信息的功能。日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过 logcat 命 令来查看和使用.使用logcat命令你可以用 logcat...

android运行时权限解决办法(含有申请权限已授权、权限被拒绝、权限勾选不在提示的回调)

转自:http://blog.csdn.net/u010823943/article/details/54565364 先说明一下:  1、Android运行时权限已经不是新东西了,我始终...

Android 6.0动态申请权限实践及遇到的坑

Android 6.0已经出了一段时间了,最近在6.0上遇到一个权限问题,在博客上稍作总结 1.在6.0系统上权限被分为NormalPermission(普通权限)以及DangerousPermi...

Android系统权限和root权限

Android权限说明 Android系统是运行在Linux内核上的,Android与Linux分别有自己的一套严格的安全及权限机制, Android系统权限相关的内容, (一)linux文件系...

[Android 6.0] 程序开发(一)--运行时请求权限

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

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

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/50709663; 本文出自:【张鸿洋的博客】 一、概述 随着A...

Android多权限请求

android权限请求权限分类 1 普通权限 2 需要申请的权限dangerous permission 动态权限申请 1 在AndroidManifestxml 文件中添加权限 2 检查权限是否被赋...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)