美文网首页
无标题文章

无标题文章

作者: 曹国强 | 来源:发表于2016-10-12 10:07 被阅读0次

    Android 6.0 运行时权限处理

    标签(空格分隔): android


    运行时权限介绍

    Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,
    又新增了运行时权限动态检测,以下权限都需要在运行时判断:

     1. 身体传感器
     2. 日历
     3. 摄像头
     4. 通讯录
     5. 地理位置
     6. 麦克风
     7. 电话
     8. 短信
     9. 存储空间
    

    运行时权限处理

    Android6.0系统默认为targetSdkVersion小于23的应用默认授予了所申请的所有权限,
    所以如果你以前的APP设置的targetSdkVersion低于23,在运行时也不会崩溃,
    但这也只是一个临时的救急策略,用户还是可以在设置中取消授予的权限。

    • 声明目标SDK版本

    我们需要在build.gradle中声明targetSdkVersion为23

        android {
         compileSdkVersion 23
         buildToolsVersion "23.0.1"
        
         defaultConfig {
             applicationId "com.yourcomany.app"
             minSdkVersion 18
             targetSdkVersion 23
             versionCode 1
             versionName "1.0"
         }
         buildTypes {
             release {
                 minifyEnabled false
                 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
             }
         }
        }
    
    • 检查并申请权限

    我们需要在用到权限的地方,每次都检查是否APP已经拥有权限,
    比如我们有一个下载功能,需要写SD卡的权限,
    我们在写入之前检查是否有WRITE_EXTERNAL_STORAGE权限,没有则申请权限

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                  != PackageManager.PERMISSION_GRANTED) {
              //申请WRITE_EXTERNAL_STORAGE权限
              ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                      WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
          }
    
    
    • 请求权限后,系统会弹出请求权限的Dialog


      image_1avg26bs49s8mv3163914mj1skn9.png-38kBimage_1avg26bs49s8mv3163914mj1skn9.png-38kB
    • 用户选择允许或拒绝后,会回调onRequestPermissionsResult方法, 该方法类似于onActivityResult
    @Override
      public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
          doNext(requestCode,grantResults);
      }
    
    
    • 我们接着需要根据requestCode和grantResults(授权结果)做相应的后续处理
    private void doNext(int requestCode, int[] grantResults) {
          if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) {
              if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  // Permission Granted
              } else {
                  // Permission Denied
              }
          }
      }
    
    

    Fragment中运行时权限的特殊处理

    • 在Fragment中申请权限,不要使用ActivityCompat.requestPermissions,
      直接使用Fragment的requestPermissions方法,否则会回调到Activity的onRequestPermissionsResult
    • 如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方法,onRequestPermissionsResult不会回调回来,建议使用getParentFragment().requestPermissions方法,
      这个方法会回调到父Fragment中的onRequestPermissionsResult,加入以下代码可以把回调透传到子Fragment
    @Override
      public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
          super.onRequestPermissionsResult(requestCode, permissions, grantResults);
          List<Fragment> fragments = getChildFragmentManager().getFragments();
          if (fragments != null) {
              for (Fragment fragment : fragments) {
                  if (fragment != null) {
                      fragment.onRequestPermissionsResult(requestCode,permissions,grantResults);
                  }
              }
          }
      }
    
    

    相关开源项目

    PermissionsDispatcher
    使用标注的方式,动态生成类处理运行时权限,目前还不支持嵌套Fragment。

    RxPermissions
    基于RxJava的运行时权限检测框架

    Grant
    简化运行时权限的处理,比较灵活

    android-RuntimePermissions
    Google官方的例子

    文/阳春面(简书作者)
    原文链接:http://www.jianshu.com/p/b4a8b3d4f587
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    相关文章

      网友评论

          本文标题:无标题文章

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