我眼中的AndroidAndroid知识Android开发经验谈

#调研一下Android 6.0临时运行权限

2017-06-23  本文已影响86人  grr1314

调研一下Android 6.0临时运行权限

调研一下原理

概述

临时运行权限是Android 6.0所带来的变化,主要是为了解决app滥用权限的现象。6.0之前的系统app安装的时候会有一个权限列表用户同意了以后才可以安装,而6.0以后用户可以直接安装app,当app需要使用某些危险权限的时候系统会给用户提示,用户可以选择拒绝和同意,同时用户可以设置里面查看app的权限。

危险权限和普通权限

Google将权限分为了两类

第一种是普通权限(Normal Permission),这些权限不会涉及用户的隐私

第二种是危险权限(Dangerous Permissions),这些权限又可以能会涉及到用户的隐私

要做的几件事

AndroidManifast.xml文件中的权限还是要添加,不然系统还是会报错

1.检查权限

ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED

2.申请权限

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, 1);

3.处理权限回调

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] 
 grantResults) 
  {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Intent intent = new Intent(Intent.ACTION_CALL);
            Uri data = Uri.parse("tel:" + phoneNumber);
            intent.setData(data);
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            startActivity(intent);
        } else {
            Toast.makeText(getApplicationContext(), "Permisson Denied", Toast.LENGTH_SHORT).show();
        }
    }
}

简单的例子

PermissionSimpleTest

常见的三方库

  1. AndPermission
  2. RxPermission
  3. PermissionGen
  4. MPermissions

常见三方库的用法

AndPermission

地址:https://github.com/yanzhenjie/AndPermission

用法:

  1. 依赖方式:

    远程依赖

    compile 'com.yanzhenjie:permission:1.0.1'

  2. 申请一个权限:

    //申请权限

     AndPermission.with(this)
             .requestCode(101)
             .permission(Manifest.permission.WRITE_CONTACTS,
                     Manifest.permission.READ_SMS,
                     Manifest.permission.WRITE_EXTERNAL_STORAGE)
             .rationale(mRationaleListener)
             .callback(listener)
             .start();
    
  3. 申请多个权限:

    //申请权限

     AndPermission.with(this)
             .requestCode(101)
             .permission(Manifest.permission.WRITE_CONTACTS,
                     Manifest.permission.READ_SMS,
                     Manifest.permission.WRITE_EXTERNAL_STORAGE)
             .rationale(mRationaleListener)
             .callback(listener)
             .start();
    
  4. 回调处理:

  1. Listener方式回调

        private PermissionListener listener = new PermissionListener() {
    
             @Override
             public void onSucceed(int requestCode, List<String> grantedPermissions) {
    
        // 权限申请成功回调。
    
        // 这里的requestCode就是申请时设置的requestCode。
       // 和onActivityResult()的requestCode一样,用来区分多个不同的请求。
         if (requestCode == 101) {
          // TODO ...
          Toast.makeText(getApplicationContext(), "申请权限成功", Toast.LENGTH_SHORT).show();
      }
      }
    
      @Override
      public void onFailed(int requestCode, List<String> deniedPermissions) {
      // 权限申请失败回调。
      if (requestCode == 101) {
          // TODO ...
          Toast.makeText(getApplicationContext(), "申请权限失败", Toast.LENGTH_SHORT).show();
        }
       }  
      };
    
  2. 注解方式回调

       // 成功回调的方法,用注解即可,里面的数字是请求时的 requestCode。
          @PermissionYes(100)
          private void getLocationYes() {
       // 申请权限成功,可以去做点什么了。
          Toast.makeText(this, "获取定位权限成功", Toast.LENGTH_SHORT).show();
          }
    
       // 失败回调的方法,用注解即可,里面的数字是请求时的 requestCode。
            @PermissionNo(100)
          private void getLocationNo() {
       // 申请权限失败,可以提醒一下用户。
              Toast.makeText(this, "获取定位权限失败", Toast.LENGTH_SHORT).show();
           }
    
  3. Rationale能力

    Android运行时权限有一个特点,就是用户在拒绝过一次权限以后,再次申请权限的时候弹出的提示框中会多一个【不再提示】的选项,
    当用户选择并拒绝申请的时候,那么以后再次申请权限将直接导致申请失败!因此为了避免用户以后一直无法申请权限,Rationale显然是
    有必要的,Rationale的功能是在用户拒绝申请之前提示用户申请这个权限的目的和用处,Rationale的提示框是开发者可以定义的。

       private RationaleListener mRationaleListener = new RationaleListener() {
         @Override
            public void showRequestPermissionRationale(int requestCode, final Rationale rationale) {
               new AlertDialog.Builder(AndPermissionActivity.this)
                   .setTitle("友好提醒")
                    .setMessage("没有定位权限将不能为您推荐附近妹子,请把定位权限赐给我吧!")
                   .setPositiveButton("好,给你", new DialogInterface.OnClickListener() {
                      @Override
                     public void onClick(DialogInterface dialog, int which) {
                         dialog.cancel();
                         rationale.resume();// 用户同意继续申请。
                     }
                 })
                 .setNegativeButton("我拒绝", new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                         dialog.cancel();
                         rationale.cancel(); // 用户拒绝申请。
                     }
                 }).show();
         }
     };
    

RxPermission

地址:https://github.com/tbruyelle/RxPermissions

PermissionGen

地址:https://github.com/lovedise/PermissionGen

用法

  1. 申请权限

     PermissionGen.with(MainActivity.this)
         .addRequestCode(100)
         .permissions(
             Manifest.permission.READ_CONTACTS,
             Manifest.permission.RECEIVE_SMS,
             Manifest.permission.WRITE_CONTACTS)
         .request();
    
  2. 回调处理

    1. 回调方式一

          @Override 
        public void onRequestPermissionsResult(int requestCode, String[] permissions,
         int[] grantResults) {
           PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
           }
      
    2.  @PermissionSuccess(requestCode = 100)           
          public void test(){
             startActivity(new Intent(this, ContactActivity.class));
          }
       @PermissionFail(requestCode = 100)
          private void test2() {
             Dlog.debug("contact fail");
        }
      

MPermissions

地址:https://github.com/hongyangAndroid/MPermissions

AndPermission和PermissionGen的对比

AndPermission的最大的有点就是有一个Rationale这对于用户是一个不错的体验,并且我们可以自定义Dialog,这是PermissionGen不具备的。
AndPermission具备在其它类中申请权限的能力,这显然也是PermissionGen不具备的
PermissionGen代码量相对较少,调用方便。
两个库都不具备判断具体哪个权限被拒绝的能力

选择一个三方库

AndPermission

参考文章:
http://blog.csdn.net/lmj623565791/article/details/50709663
http://www.jianshu.com/p/a1edba708761

上一篇 下一篇

猜你喜欢

热点阅读