Android6.0动态获取权限

                         Android6.0动态获取权限

  Android系统从6.0开始对用户权限的控制更加严格,系统将权限分为了两个级别,常规权限和危险权限;
    1、常规权限:不会涉及用户隐私操作的权限,如读写存储卡;
    2、危险权限:涉及用户隐私的权限,如读取电子邮件和通讯录;

    Android将需要申请的权限依次在manifest中注册,
    如<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
    当用户执行需要权限的操作时,系统会检查当前应用是否具有相应的操作权限,
    在Android6.0之前,会在安装应用的时候申请权限,如果用户不同意,
    则无法完成安装,但是在6.0之后,申请限向变成了动态申请的模式,即当用户应用要使用某项权
    限才能进行相应操作时,每次都需要去检查是否拥有相应的权限,当申请的是常规权限的时候,
    系统会默认同意权限,申请的是危险权限的时候,系统会弹出询问框提示用户是否授权该应用相应的
    权限。

-------------------------------------------------------------------------------------------------------------------
 方法一:
    自己手动请求权限。
    参考:https://developer.android.google.cn/training/permissions/requesting.html

    1,注册权限;
        <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>

    2、检查权限:
       在Activity/Fragment中相应的方法里调用ContextCompat.checkSelfPermission()方法,
       检查是否拥有相依的权限

    调用ContextCompat的方法检查权限:
    int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
    Manifest.permission.WRITE_CALENDAR);


    public void checkPermission(){
                int tag= ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_CONTACTS);
                  if(tag== PackageManager.PERMISSION_DENIED){//没有权限
                     //需要执行申请权限操作
                    ActivityCompat.requestPermissions(MainActivity.this,
                         new String[]{Manifest.permission.READ_CONTACTS},
                          MY_PERMISSIONS_REQUEST_READ_CONTACTS);
                }else if (tag==PackageManager.PERMISSION_GRANTED){//有权限
                    //执行目标代码
                    callMyPhone();
                }
          }

    3、申请权限:
       MY_PERMISSIONS_REQUEST_READ_CONTACTS:请求码,申请成功或失败后会在
       onRequestPermissionsResult方法中作为某项权限的标识。

       ActivityCompat.requestPermissions(MainActivity.this,new String[]{
           Manifest.permission.READ_CONTACTS},
       MY_PERMISSIONS_REQUEST_READ_CONTACTS);

       复写Activity/Fragment的onRequestPermissionsResult方法,这里以Activity为例:

       @Override
       public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
        @NonNull int[] grantResults) {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
              switch (requestCode){
                case MY_PERMISSIONS_REQUEST_READ_CONTACTS://申请成功
                     if (grantResults.length > 0 && grantResults[0] ==
                     PackageManager.PERMISSION_GRANTED) {//申请成功

                       //成功要执行的方法
                        callMyPhone();

                     } else {//申请失败

                          //失败要执行的方法

                      }
               break;
              }

        }

  4、申请权限成功或者失败,完成相应的操作:
       当权限申请成功后,会异步回调onRequestPermissionsResult方法,requestCode就是申请某
       项权限是传入的请求码,这里是MY_PERMISSIONS_REQUEST_READ_CONTACTS,通过requestCode
       来判断是申请的那项权限,grantResults是权限申请的结果,是一个数组,判断是成功还是
       失败,并且执行相应的方法。



       全部代码:
     =================

       public class MainActivity extends AppCompatActivity {
       public static int MY_PERMISSIONS_REQUEST_CALL_PHONE = 100;
       private static final int MY_PERMISSIONS_REQUEST_READ_CONTACTS=100;
         @Override
       protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
       }



       public void checkPermission(){
              int tag= ContextCompat.checkSelfPermission(this,
              Manifest.permission.READ_CONTACTS);

              if(tag== PackageManager.PERMISSION_DENIED){//没有权限
                //需要执行申请权限操作
                ActivityCompat.requestPermissions(MainActivity.this,
                     new String[]{Manifest.permission.READ_CONTACTS},
                     MY_PERMISSIONS_REQUEST_READ_CONTACTS);
             }else if (tag==PackageManager.PERMISSION_GRANTED){//有权限
                 //执行目标代码
                callMyPhone();
              }
       }
       //指向访问通讯
       public void callMyPhone() {
            Uri uri =ContactsContract.Contacts.CONTENT_URI;
            Intent intent = new Intent(Intent.ACTION_PICK, uri);
            startActivityForResult(intent,0);

       }

       @Override
       public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
         @NonNull int[] grantResults) {
              super.onRequestPermissionsResult(requestCode, permissions, grantResults);
              switch (requestCode){
              case MY_PERMISSIONS_REQUEST_READ_CONTACTS:
               if (grantResults.length > 0
               && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//申请成功
                     //成功要执行的方法
                     callMyPhone();
                } else {//申请失败
                     //失败要执行的方法
                }

                  break;
            }
}

--------------------------------------------------------------------------------------------

       方法二:
      ===============
       使用三方的库;
       常用的库有很多,比较好的有easypermissions和PermissionsDispatcher等,
       开源地址为:
        easypermissions:https://github.com/googlesamples/easypermissions
        PermissionsDispatcher:https://github.com/hotchemi/PermissionsDispatcher

       这里以PermissionsDispatcher为例:该库是使用反射机制来做的,但是右一个亮点是将
       提前到了编译器,通过反射生成辅助来供相应的类在运行时调用,所以该库基本不因为反射
       影响应用的性能。


       注意:当gradle版本不一样的时候,引入配置方式有所不同


       1)、当Gradle 版本>= 2.2的引入方式;
         在当前module的gradle中依赖库:
         dependencies {
              compile 'com.github.hotchemi:permissionsdispatcher:2.3.1'
              annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.1'
         }

       2)、当Gradle 版本< 2.2的引入方式;
         《1》中工程的gradle中
          buildscript {
          dependencies {
               classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
                 }
              }

           repositories {
              jcenter()
              // 需要添加的配置
              maven { url 'http://oss.jfrog.org/artifactory/oss-snapshot-local/' }
              }

       《2》在module的gradle中配置:
              头部添加
              apply plugin: 'com.android.application'//你的module配置不用动
              apply plugin: 'android-apt'//新添加的配置


       依赖库
           dependencies {
              compile 'com.github.hotchemi:permissionsdispatcher:2.3.1'
              annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.1'
          }

       根据不同gradle的版本配置完成后重新构建工程,接下来就是正式使用了。


       在Activity或Fragment中使用
       ------------------------------------------------------------------------------------
       注解列表:

       Annotation             Required    Description
       @RuntimePermissions    必须       注解在其内部需要使用运行时权限的Activity或
                                          Fragment上
       ------------------------------------------------------------------------------------
       @NeedsPermission      必须        注解在需要调用运行时权限的方法上,当用户给予权限时
                                          会执行该方法
       ------------------------------------------------------------------------------------
       @OnShowRationale      可选        注解在用于向用户解释为什么需要调用该权限的方法上,
                                          只有当第一次请求权限被用户拒绝,下次请求权限之前会
                                          调用
       ------------------------------------------------------------------------------------
       @OnPermissionDenied   可选       注解在当用户拒绝了权限请求时需要调用的方法上
       ------------------------------------------------------------------------------------
       @OnNeverAskAgain      可选        注解在当用户选中了授权窗口中的不再询问复选框后并拒
                                          绝了权限请求时需要调用的方法,一般可以向用户解释为
                                          何申请此权限,并根据实际需求决定是否再次弹出权限请
                                          求对话框
      ------------------------------------------------------------------------------------
       官网参考地址:http://hotchemi.github.io/PermissionsDispatcher/

       注意:被注解的方法不能是私有方法。
       只有@RuntimePermissions和@NeedsPermission是必须的,其余注解均为可选。当使用了
       @RuntimePermissions和@NeedsPermission之后,需要点击菜单栏中Build菜单下的Make Project
       ,或者按快捷键Ctrl+ F9编译整个项目,编译器会在app\build\intermediates\classes\debug
       目录下与被注解的Activity同一个包下生成一个辅助类,
       名称为被注解的Activity名称+PermissionsDispatcher.class

       接下来可以调用辅助类里面的方法完成应用的权限请求了。

       在需要调用权限的位置调用辅助类里面的xxxWithCheck方法,xxx是被@NeedsPermission注
       解的方法名。如:

       MainActivityPermissionsDispatcher.showCameraWithCheck(this);


       全部代码:
      ==================

       注解Activity为运行时权限
       @RuntimePermissions
        public class MainActivity extends AppCompatActivity {
           @Override
            protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
           }


       /**
       *  执行的事件
       * @param
        */
       public void app(View v) {
              MainActivityPermissionsDispatcher.callPhoneWithCheck(this);//检查权限
            }


       /**
       * 当权限申请成功后被执行的代码
       *  注解当某项权限申请成功后被调用的方法
       */
              @NeedsPermission(Manifest.permission.READ_CONTACTS)
              public void callPhone() {
                Uri uri = ContactsContract.Contacts.CONTENT_URI;
                Intent intent = new Intent(Intent.ACTION_PICK, uri);
                startActivityForResult(intent, 0);
               }


       /**
       * 复写Activity或者Fragment的处理权限的方法
       *  当申请了权限时会被异步调用
       */
          @Override
          public void onRequestPermissionsResult(int requestCode, @NonNull String[] 
          permissions,@NonNull int[] grantResults) {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
              //调用生成辅助类的方法
              MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode,
              grantResults);
            }


       /**
       * 当权限被拒绝后要调用的方法
       */
       @OnPermissionDenied(Manifest.permission.READ_CONTACTS)
       public void onPermissionDenied() {

        }

       }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值