無標題文章

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-38kB
    image_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.lxweimin.com/p/b4a8b3d4f587
著作權歸作者所有,轉載請聯系作者獲得授權,并標注“簡書作者”。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,813評論 25 708
  • 1.要做一個盡可能流暢的ListView,你平時在工作中如何進行優化的? ①Item布局,層級越少越好,使用hie...
    fozero閱讀 743評論 0 0
  • spring官方文檔:http://docs.spring.io/spring/docs/current/spri...
    牛馬風情閱讀 1,716評論 0 3
  • 昨天和好友聊天,她指出了我的行事特點。聽到她說出口的那一刻,我的心很痛!不是因為她的直言,而是因為她說的確是事實,...
    cutelyd閱讀 929評論 0 0
  • 2016.1.16 晚 無聊之際,刷微博看到一個視頻,心里莫名的難過http://m.weibo.cn/29788...
    張堂玉閱讀 228評論 0 0