Android M新的运行时权限开发者需要知道的一切

如果permissions没有影响到用户的隐私,系统就会自动授权。如果权限可能会访问到敏感的用户信息,系统则会要求用户处理这种权限要求。

系统permissions被分为两类,normal和dangerous:

  • Normal permissions不会直接触及到用户的隐私,如果你的app已经在Manifest文件中列出了常规权限,系统则会自动授权。

  • dangerous的权限能够给app访问用户可信任的数据,如果你的app在Manifest中列出了常规权限,系统则会自动许可。如果你列出了危险权限,那么用户就必须明确地给你的app授权。

然而有效的声明是不同的,这需要依赖于系统的版本以及你的app的target SDK级别:

  • 如果手机运行在android 5.1或者更低,或者你的app的target SDK是22或更低的情况:如果你把dangerous permission列在了Manifest中,则用户必须在安装的时候就要授权;如果他们没有授权权限,则系统就不能安装该应用。
  • 如果手机运行在android 6.0或者更高,并且你的app的SDK是23或者更高的情况:app必须在Manifest列出这些permissions,并且它会在app运行的时候询问每一个它需要的dangerous permission。用户可以授权或者拒绝每一个权限,并且app能够在受限的情况下继续运行,即使用户拒绝了一个permission的请求。

Note:从android 6.0(API level23),用户能够在任何app任何时候取消permissions,即使apptargets 在一个更低的API level下。

检查权限

检查是否有permission,调用ContextCompat.checkSelfPermission()方法。例如下面一段代码展示了怎样检查当activity有permission写日历的权限:
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);
如果app拥有了该permission,则方法返回PackageManager.PERMISSION_GRANTED,app 能继续这种操作。如果app没有该permission,则方法返回PERMISSION_DENIED,并且app必须明确向用户要求给permission。

请求权限

如果你的app需要一个dangerous permission,并且已经被列在了Manifest中,那么它必须要求用户去给该permission授权。Android提供了若干个方法,你能够使用它们去请求permission。调用这些方法会弹出一个你不能够自定义的标准android dialog。

向用户解释为什么app需要permissions

在某些情况下,你也许想帮助用户理解为什么app需要permission。在你请求一个permission之前,你需要考虑给用户一个合理的解释。请记住,你不会希望用户被说明淹没的,如果你提供了太多的解释,用户或许会发现app令人沮丧,甚至删掉它。
当用户已经拒绝了一个permission请求的时候,你可以使用的一个方法是提供一个解释。如果用户一直试图使用的功能需要一个permission的许可,但是又一直拒绝许可该permission的要求,这或许表明该用户不理解为什么app需要提供该功能。在这种情况下,给用户一个解释或许是个好的方法。
为了找到哪些用户可能需要的解释的情况,android提供了一个使用的方法,shouldShowRequestPermissionRationale().该方法返回true,如果应用程序要求这个许可之前,用户拒绝请求。

Note:如果用户在以前拒绝了permission的请求,并且在permission请求的系统对话框中选择了Don’t ask again的选项,这个方法返回false。如果手机政策禁止应用程序拥有该权限也会返回false。

请求你需要的permission

如果app已经没有它需要的permission,那么app必须调用一个requestPermissions()方法去请求适当的permission。App传递它想要的permissions,以及一个你指定识别此permission整数的request code 。这个方法有同步功能:它立即返回,并在用户响应了对话框后,系统会调用app与结果的的回调方法,通过该app传递给requestPermissions()相同request code。
下面的代码检查app是否有读取用户联系人的permission,并在必要时请求允许:

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

处理permissions请求的响应

当你的app请求权限,系统就会向用户显示一个对话框。当用户相应了对对话框,系统就会调用app的onRequestPermissionsResult()方法,传递用户的响应。你的app必须重写该方法,并确定权限是否允许,回调被传递的request和requestPermissions()传递的request code是相同的。例如,如果app请求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 
    } 
}

该系统显示的对话框中描述的app需要访问权限组;它没有列出具体的权限。例如,如果你要求READ_CONTACTS权限,系统对话框,只是说你的应用程序需要访问该设备的联系人。用户只需要为每个权限组授予权限一次。如果app请求组(即在app清单中列出)中任何其他权限,系统自动授权他们。当你请求该权限,系统调用你的onRequestPermissionsResult()回调方法,并传递PERMISSION_GRANTED,它会在用户已明确授予通过系统对话框,你的要求是一样的。

Note:此外,权限的组成组可能会在将来的Android版本中改变。你的代码不应该依赖于假设特定的权限,或不在同一组。

例如,假设你列出的应用程序清单既有READ_CONTACTS也有WRITE_CONTACTS。如果你请求READ_CONTACTS和用户授予权限,然后你要求WRITE_CONTACTS,系统自动授予你该权限,而不必再与用户交互了。
如果用户拒绝了权限要求,你的app应该采取适当的行动。例如,你的应用程序可能会显示一个对话框,解释为什么它不能执行用户的请求的操作需要该权限。
当系统要求用户授予权限,用户告知系统不要再问了该权限的选项。在这种情况下,任何时间的应用程序使用requestPermissions()再次要求该权限,系统会立即拒绝请求。该系统调用你的onRequestPermissionsResult()回调方法,并传递PERMISSION_DENIED,以同样的方式,将如果用户曾明确再次拒绝你的要求。这意味着,当你调用requestPermissions(),你不能假设与用户进行任何直接的互动已经发生。

参考: Android M新的运行时权限开发者需要知道的一切
https://developer.android.com/training/permissions/requesting.html#perm-request

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值