美文网首页
关于android6.0的权限申请

关于android6.0的权限申请

作者: 刘孙猫咪 | 来源:发表于2017-06-30 23:10 被阅读0次

    谷歌在android6.0的权限管理方面做了不少的改动,android6.0以前的话需要什么权限只需要在AndroidManifest文件中进行申请就可以了,android6.0以后的话将权限分为两类;一类是Normal Permissions,这类权限一般不涉及用户隐私,是不需要用户进行授权的,比如手机震动、访问网络等;另一类是Dangerous Permission,一般是涉及到用户隐私的,需要用户进行授权,比如读取sdcard、访问通讯录等;对于Normal Permissions的话还是跟之前一样的做法,Dangerous Permission的话不仅需要在AndroidManifest中注册,还需要动态申请;下面这些的就是Dangerous Permission:

    group:permission-group.CONTACTS 
    permission: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 
    

    对于这些权限在使用的时候就需要注意,要记得动态去申请添加权限;这里也讲下本人的一个大致思路:

    1:判断当前的版本是否在android6.0及以上,如果不是就直接AndroidManifest中申请,
    2:android6.0及以上的话,判断用户是否赋予该权限,如果赋予该权限,就运行进行相应的操作,
    3:6.0及以上同时没有赋予该权限,就动态的申请并提示用户赋予该权限,,如果赋予该权限,就运行进行相应的操作,如果用户拒绝,就提示用户拒绝该权限的赋予,同时不允许用户进行相应操作,如果用户继续操作,还是提示用户要赋予该权限;
    

    其实在http://blog.csdn.net/wangwo1991/article/details/54666737;
    这篇博客中已经讲过6.0权限的处理,不过这是另外一种思路处理,这里要讲的是通过反射和注解的方式处理6.0的权限;反射和注解的话在IOC注解里面已经讲到过了;就直接写成功和失败的注解了;

    成功的注解:

    @Target(ElementType.METHOD)//ElementType.METHOD方法上面  Target代表放在什么位置
    @Retention(RetentionPolicy.RUNTIME)//是编译时检测还是运行时检测  Retention代表什么时候去检测
    public @interface PermissionSuccess {
        public int requestCode();//请求码
    }
    

    失败的注解:

    @Target(ElementType.METHOD)//ElementType.METHOD方法上面  Target代表放在什么位置
    @Retention(RetentionPolicy.RUNTIME)//是编译时检测还是运行时检测  Retention代表什么时候去检测
    public @interface PermissionFail {
        public int requestCode();//请求码
    }
    

    首先判断当前系统的版本;

    /**
         * 判断其是不是6.0以上的版本
         * @return
         */
        public static boolean isOverMarshmallow(){
            return Build.VERSION.SDK_INT>=Build.VERSION_CODES.M;
        }
    

    根据系统的版本去执行权限的申请或者相应的操作;

          //首先判断当前的版本是不是6.0和6.0以上
            if (!PermissionUtils.isOverMarshmallow()) {
                //如果不是6.0以上,  反射获取执行方法
                PermissionUtils.executeSuccess(mObject,mRequestCode);
                return;
            }
            //如果是6.0以上那么首先需要判断是否授予权限
            List<String> deniedPermission=PermissionUtils.getDeniedPermission(mObject,mPermisson);
            //如果授予了 反射获取执行方法
            if(deniedPermission.size()==0){
                //全部都是授予过权限的
                PermissionUtils.executeSuccess(mObject,mRequestCode);
            }else{
                //如果没有授予 那么我们就申请
                ActivityCompat.requestPermissions(PermissionUtils.getActivity(mObject),
                        deniedPermission.toArray(new String[deniedPermission.size()]),
                        mRequestCode);
            }
    

    如果是6.0及以上并没有授予权限,就需要去动态申请,谷歌提供了

    ActivityCompat.requestPermissions(PermissionUtils.getActivity(mObject),
                        deniedPermission.toArray(new String[deniedPermission.size()]),
                        mRequestCode);
    

    方法可以去申请权限,当然了肯定还要去处理申请后的回调;

      public static void requestPermissionsResult(Object mObject,int requestCode, String[] permissions, int[] grantResults) {
            //再次获取是否授予的权限
            List<String> deniedPermission=PermissionUtils.getDeniedPermission(mObject,permissions);
            if(deniedPermission.size()==0){
                //这些权限全部同一
                PermissionUtils.executeSuccess(mObject,requestCode);
            }else{
                //申请中权限中有用户不同意的
                PermissionUtils.executeFailMethod(mObject,requestCode);
            }
        }
    

    申请的过程以及成功或者失败都是通过反射来执行和实现;如果是成功的话,通过invoke();方法去执行相应的操作;

      public static void executeSuccess(Object mOhject, int requestCode) {
            //获取class中所有的方法
            Method[] methods = mOhject.getClass().getDeclaredMethods();
            for(Method method:methods){
                System.out.println("--------"+method);
                //获取该方法上有没有打这个成功的标记
                PermissionSuccess successMethod = method.getAnnotation(PermissionSuccess.class);
                if(successMethod!=null){
                    //代表该方法打了标记
                    //遍历找到打了标记的方法并且我们的请求码要一致
                    int methodCode = successMethod.requestCode();
                    if(methodCode==requestCode){
                        //这个就是我们要找的成功的方法
                        //反射执行该方法
                        executeMethod(mOhject,method);
                    }
                }
            }
        }
    

    通过反射获取该类中所有的方法,根据传入的requestCode和方法注解中的methodCode对比,如果一致的话,就调用executeMethod();去执行;

      private static void executeMethod(Object mOhject,Method method) {
            //反射执行方法  第一个参数是该方法是属于哪个类  第二个参数是传参数
            try {
                method.setAccessible(true);//运行执行私有方法
                method.invoke(mOhject,new Object[]{});//反射执行方法
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    

    获取失败的处理和执行也是一样的;

        /**
         * 执行失败的方法
         * @param mObject
         * @param requestCode
         */
        public static void executeFailMethod(Object mObject, int requestCode) {
            //获取class中所有的方法
            Method[] methods = mObject.getClass().getDeclaredMethods();
            for(Method method:methods){
                System.out.println("--------"+method);
                //获取该方法上有没有打这个失败的标记
                PermissionFail failMethod = method.getAnnotation(PermissionFail.class);
                if(failMethod!=null){
                    //代表该方法打了标记
                    //遍历找到打了标记的方法并且我们的请求码要一致
                    int methodCode = failMethod.requestCode();
                    if(methodCode==requestCode){
                        //这个就是我们要找的成功的方法
                        //反射执行该方法
                        executeMethod(mObject,method);
                    }
                }
            }
        }
    

    这里提供了Activity、Fragment以及FragmentActivity的使用,调用下面这些方法进行请求码和需要申请的权限;

      //传请求码
        public PermissionHelper requestCode(int requestCode) {
            this.mRequestCode = requestCode;
            return this;
        }
    
        //传请求权限
        public PermissionHelper requestPermission(String... permisson) {
            this.mPermisson = permisson;
            return this;
        }
    

    使用的时候肯定是要先进行权限的申请;

    PermissionHelper.with(MainActivity.this).
                            requestPermission(new String[]{Manifest.permission.CALL_PHONE}).
                            requestCode(CALL_PHONE_REQUEST_DODE).
                            request();
    
    @PermissionSuccess(requestCode =CALL_PHONE_REQUEST_DODE)
        private void callPhone(){
            Intent intent=new Intent(Intent.ACTION_CALL);
            Uri data=Uri.parse("tel:"+"15889548152");
            intent.setData(data);
            startActivity(intent);
        }
    

    这里是成功要执行的相应操作;如果需要对失败也进行相应提示的话,写一个失败的方法就可以了,也可以不处理;

    @PermissionFail(requestCode =CALL_PHONE_REQUEST_DODE)
        private void callPhoneFail(){
            Toast.makeText(this, "你拒绝了拨打电话", Toast.LENGTH_SHORT).show();
        }
    

    下面这个的话是申请结果的一个回调;

      @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            PermissionHelper.requestPermissionsResult(this,requestCode,permissions,grantResults);
        }
    

    这样就ok了,使用起来还是蛮简单的,效果如下:

    GIF.gif

    源码地址:http://pan.baidu.com/s/1sldiMx3

    相关文章

      网友评论

          本文标题:关于android6.0的权限申请

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