Android权限(二)

作者: 小飞侠在吗 | 来源:发表于2017-01-05 19:54 被阅读0次

    Android权限(一)中,介绍了Android中的所有权限。随着Android 6.0发布以及普及,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化。

    Android6.0 权限变化

    在Android 6.0版本之前,只要用户安装完,AndroidManifest清单上申请的权限都会被系统默认授权,并且授权后也撤销不了。弊端就是,即使权限用户不需要,但是也去不掉。一些恶意程序,会利用这个权限默认授权,进行恶意获取用户数据和攻击。Android6.0采用新的权限模型,只有在需要权限的时候,才告知用户是否授权,是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候,需要先检查是否有所需要的权限申请。这样的用户的自主性提高很多,比如用户可以给APP赋予摄像的权限,但是可以拒绝记录设备位置的权限,就是怕位置信息上传等等。

    Android6.0 权限分类

    权限分为了正常权限和危险权限。
    正常权限涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。例如,设置时区的权限就是正常权限。如果应用声明其需要正常权限,系统会自动向应用授予该权限。如需当前正常权限的完整列表,请参阅正常权限
    危险权限涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。**例如,能够读取用户的联系人属于危险权限。如果应用声明其需要危险权限,则用户必须明确向应用授予该权限。正常权限有很多个,现在着重介绍一下危险权限。

    危险权限和权限组

    所有危险的 Android 系统权限都属于权限组。如果设备运行的是 Android 6.0(API 级别 23),并且应用的 targetSdkVersion
    是 23 或更高版本,则当用户请求危险权限时系统会发生以下行为:
    如果应用请求其清单中列出的危险权限,而应用目前在权限组中没有任何权限,则系统会向用户显示一个对话框,描述应用要访问的权限组。对话框不描述该组内的具体权限。例如,如果应用请求 READ_CONTACTS
    权限,系统对话框只说明该应用需要访问设备的联系信息。如果用户批准,系统将向应用授予其请求的权限。
    如果应用请求其清单中列出的危险权限,而应用在同一权限组中已有另一项危险权限,则系统会立即授予该权限,而无需与用户进行任何交互。例如,如果某应用已经请求并且被授予了 READ_CONTACTS
    权限,然后它又请求 WRITE_CONTACTS
    ,系统将立即授予该权限。

    任何权限都可属于一个权限组,包括正常权限和应用定义的权限。但权限组仅当权限危险时才影响用户体验。可以忽略正常权限的权限组。
    如果设备运行的是 Android 5.1(API 级别 22)或更低版本,并且应用的 targetSdkVersion
    是 22 或更低版本,则系统会在安装时要求用户授予权限。再次强调,系统只告诉用户应用需要的权限,而不告知具体权限。

    危险权限和权限组,如下图:


    危险权限和权限组.png

    定义和实施权限

    要实施您自己的权限,必须先使用一个或多个 <permission>
    元素在 AndroidManifest.xml
    中声明它们。
    基于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.
        }
    }
    

    请求要使用的权限:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
         ActivityCompat.requestPermissions(this, 
                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
                         Manifest.permission.WRITE_EXTERNAL_STORAGE, 
                        Manifest.permission.READ_PHONE_STATE},2); 
    }else {
        startActivity(new Intent(this,MainActivity.class));
         finish();
     }
    

    第三步:处理权限请求结果

    /**
      *动态权限申请后系统的回调方法
      */
    @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
        }
    }
    

    第四步:要注意这个方法,用户允许或拒绝返回值的类型

    /** 
     * 用户第一次拒绝后,下一次,返回true,应该提示用户为什么需要这个权限,添加说明 
     * 用户第二次请求权限时,用户拒绝了,并选择了不再提醒,返回false 
     * 设备的策略禁止当前应用获取这个权限的授权,返回false  
     * 注意:第二次请求权限时候才有选项“不再提醒”,如果用户一直拒绝,但没有选择不再提醒,下次请求权限时候,
     * 会继续有不再提醒的权限  
    */
     @Override 
    public boolean shouldShowRequestPermissionRationale(String permission) {
         return super.shouldShowRequestPermissionRationale(permission); 
    }
    

    以上就是Google官方的权限申请方法,有错请轻喷

    相关文章

      网友评论

        本文标题:Android权限(二)

        本文链接:https://www.haomeiwen.com/subject/ocgzvttx.html