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

作者: grr1314 | 来源:发表于2017-06-23 14:32 被阅读86次

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

    调研一下原理

    概述

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

    危险权限和普通权限

    Google将权限分为了两类

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

    • 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_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),这些权限又可以能会涉及到用户的隐私

    • group:android.permission-group.CONTACTS
      • permission:android.permission.WRITE_CONTACTS
      • permission:android.permission.GET_ACCOUNTS
      • permission:android.permission.READ_CONTACTS
    • group:android.permission-group.PHONE
      • permission:android.permission.READ_CALL_LOG
      • permission:android.permission.READ_PHONE_STATE
      • permission:android.permission.CALL_PHONE
      • permission:android.permission.WRITE_CALL_LOG
      • permission:android.permission.USE_SIP
      • permission:android.permission.PROCESS_OUTGOING_CALLS
      • permission:com.android.voicemail.permission.ADD_VOICEMAIL
    • group:android.permission-group.CALENDAR
      • permission:android.permission.READ_CALENDAR
      • permission:android.permission.WRITE_CALENDAR
    • group:android.permission-group.CAMERA
      • permission:android.permission.CAMERA
    • group:android.permission-group.SENSORS
      • permission:android.permission.BODY_SENSORS
    • group:android.permission-group.LOCATION
      • permission:android.permission.ACCESS_FINE_LOCATION
      • permission:android.permission.ACCESS_COARSE_LOCATION
    • group:android.permission-group.STORAGE
      • permission:android.permission.READ_EXTERNAL_STORAGE
      • permission:android.permission.WRITE_EXTERNAL_STORAGE
    • group:android.permission-group.MICROPHONE
      • permission:android.permission.RECORD_AUDIO
    • group:android.permission-group.SMS
      • permission:android.permission.READ_SMS
      • permission:android.permission.RECEIVE_WAP_PUSH
      • permission:android.permission.RECEIVE_MMS
      • permission:android.permission.RECEIVE_SMS
      • permission:android.permission.SEND_SMS
      • permission:android.permission.READ_CELL_BROADCASTS

    要做的几件事

    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

    相关文章

      网友评论

      本文标题:#调研一下Android 6.0临时运行权限

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