PermissionsDispatcher,Android 6.0 運行時權限

運行時權限

從 Android 6.0(API 級別 23)開始,用戶開始在應用運行時向其授予權限,而不是在應用安裝時授予。html

系統權限分爲兩類:android

  • 正常權限:只需在你應用的 Androidmanifest.xml 中列出,安裝時受權。
  • 危險權限:須要在你應用的 Androidmanifest.xml 中列出,並在運行時受權。

如需瞭解更多關於正常權限與危險權限能夠參閱這裏git

關於 Android 6.0 運行時權限的詳細講解能夠看這篇文章官方文檔github

運行時權限的加入增長了用戶隱私的安全,但同時也給開發者帶來了一些負擔,由於多了檢查權限,請求權限,處理權限請求響應的步驟。api

因而就出現了一些框架,用於簡化運行時權限的處理,如 PermissionsDispatcherDexterRxPermissionseasypermissions 等。安全

這裏只用過 easypermissions 和 PermissionsDispatcher,最終選擇了 PermissionsDispatcher,緣由是使用人數最多,api 設計簡單易用,兼容性較好,easypermissions 使用起來相對麻煩一些。app

PermissionsDispatcher

PermissionsDispatcher 提供簡單的基於註解的 api 處理 Android Marshmallow 下的運行時權限(非反射方式)。框架

項目地址:https://github.com/hotchemi/PermissionsDispatchermaven

一. 集成說明

注意把 ${latest.version} 改成最新版本ide

打開命令行,cd 到工程根目錄,執行 gradlew -version 或者 gradlew -v 命令查看當前工程 gradle 版本。

根據 gradle 版本進行以下配置:

Android Gradle Plugin >= 2.2

在 app 模塊下的 build.gradle 添加下面的配置:

dependencies {
  compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}'
  annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}'
}

Android Gradle Plugin < 2.2

在 project-level 下的 build.gradle 添加下面配置:

buildscript {
  dependencies {
    classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
  }
}

而後,在 app 模塊下的 build.gradle 添加下面配置:

apply plugin: 'android-apt'

dependencies {
  compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}'
  apt 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}'
}

二. 使用說明

1. 添加註解

注意:註解的方法不能是 private 的。

相關注解說明

註解 是否必須 描述
@RuntimePermissions 註冊一個 ActivityFragment 用於處理權限
@NeedsPermission 註解一個方法,說明須要什麼權限(一個或多個)
@OnShowRationale   註解一個方法,解釋爲何須要這些權限
@OnPermissionDenied   註解一個方法,當用戶拒絕受權時將調用該方法
@OnNeverAskAgain   註解一個方法,當用戶選擇了 "再也不提醒" 將調用該方法

示例代碼

@RuntimePermissions 
public class MainActivity extends AppCompatActivity {

    // 單個權限
    // @NeedsPermission(Manifest.permission.CAMERA)
    // 多個權限
    @NeedsPermission({ Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO })
    void showCamera() {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
                .addToBackStack("camera")
                .commitAllowingStateLoss();
    }
    
    // 向用戶說明爲何須要這些權限(可選)
    @OnShowRationale(Manifest.permission.CAMERA)
    void showRationaleForCamera(final PermissionRequest request) {
        new AlertDialog.Builder(this)
            .setMessage(R.string.permission_camera_rationale)
            .setPositiveButton(R.string.button_allow, (dialog, button) -> request.proceed())
            .setNegativeButton(R.string.button_deny, (dialog, button) -> request.cancel())
            .show();
    }

    // 用戶拒絕受權回調(可選)
    @OnPermissionDenied(Manifest.permission.CAMERA)
    void showDeniedForCamera() {
        Toast.makeText(this, R.string.permission_camera_denied, Toast.LENGTH_SHORT).show();
    }

    // 用戶勾選了「再也不提醒」時調用(可選)
    @OnNeverAskAgain(Manifest.permission.CAMERA)
    void showNeverAskForCamera() {
        Toast.makeText(this, R.string.permission_camera_neverask, Toast.LENGTH_SHORT).show();
    }
}

2. 調用自動生成的輔助類

註解寫好後,Build ——> Make Module ***PermissionsDispatcher 會生成一個 MainActivityPermissionsDispatcher(Activity Name + PermissionsDispatcher),你可使用它來安全地訪問這些授權限保護的方法。

你惟一須要作的一件事是將工做委託給這個輔助類:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.button_camera).setOnClickListener(v -> {
      // 調用帶權限檢查的 showCamera 方法
      MainActivityPermissionsDispatcher.showCameraWithCheck(this);
    });
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    // 代理權限處理到自動生成的方法
    MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}

*PermissionDispatcher.*WithCheck 方法對你原來的方法進行了包裝,包了一層權限檢查的代碼,你須要作的就是把原來的方法調用改成 *PermissionDispatcher.*WithCheck。另外,在 onRequestPermissionsResult 中回調 *PermissionsDispatcher.onRequestPermissionsResult 方法。

三. 獲取特殊權限

兩個特殊權限:

  • Manifest.permission.SYSTEM_ALERT_WINDOW:顯示懸浮窗
  • Manifest.permission.WRITE_SETTINGS:讀寫系統設置

對於這兩個權限,在 Android 下默認是須要到 Settings -> Apps 中手動受權的。因爲不一樣 ROM 狀況可能還有點不同。

PermissionsDispatcher 對於兩個特殊權限也作了兼容處理(Android6.0+),使用方法如上同樣。

若是須要兼容低版本的 Android 系統或者不一樣 ROM 能夠參考這個開源項目

四. maxSdkVersion

<uses-permission> 有一個 maxSdkVersion 屬性,PermissionsDispatcher 對它也作了支持。

好比,在 Androidmanifest.xml 中定義了以下權限:

<uses-permission
     android:name="android.permission.WRITE_EXTERNAL_STORAGE"
     android:maxSdkVersion="18" />

註解中添加 maxSdkVersion

@RuntimePermissions
public class MainActivity extends AppCompatActivity {

    @NeedsPermission(value = Manifest.permission.WRITE_EXTERNAL_STORAGE, maxSdkVersion = 18)
    void getStorage() {
        // ...
    }
    
}

PermissionsDispatcher Plugin

PermissionsDispatcher Plugin 是 PermissionsDispatcher 的輔助插件,支持自動生成權限檢查相關代碼。

項目地址:https://github.com/shiraji/permissions-dispatcher-plugin

安裝說明:Android Studio 中打開 Setting,Plugins ——> Browse repositories... 搜索 PermissionsDispatcher plugin,點 Install 下載安裝,安裝完成後重啓生效。

image

使用說明:

  1. 在 Activity/Fragment 中,Generate -> Generate Runtime Permissions...
  2. 選擇權限併爲每一個註解輸入方法名
  3. 點擊 Generate ,完成

使用過程當中發現有兩個小問題須要注意一下:

  1. 屢次生成代碼,onRequestPermissionsResult 方法也會被自動添加屢次
  2. 代碼生成後會提示你是否 rebuild 工程,建議選擇取消,Build ——> Make Module *** 相對快些

做者:linchaolong 連接:https://www.jianshu.com/p/64e7334cde11 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。

相關文章
相關標籤/搜索