從 Android 6.0(API 級別 23)開始,用戶開始在應用運行時向其授予權限,而不是在應用安裝時授予。html
系統權限分爲兩類:android
如需瞭解更多關於正常權限與危險權限能夠參閱這裏。git
運行時權限的加入增長了用戶隱私的安全,但同時也給開發者帶來了一些負擔,由於多了檢查權限,請求權限,處理權限請求響應的步驟。api
因而就出現了一些框架,用於簡化運行時權限的處理,如 PermissionsDispatcher,Dexter,RxPermissions,easypermissions 等。安全
這裏只用過 easypermissions 和 PermissionsDispatcher,最終選擇了 PermissionsDispatcher,緣由是使用人數最多,api 設計簡單易用,兼容性較好,easypermissions 使用起來相對麻煩一些。app
PermissionsDispatcher 提供簡單的基於註解的 api 處理 Android Marshmallow 下的運行時權限(非反射方式)。框架
注意把 ${latest.version}
改成最新版本。ide
打開命令行,cd 到工程根目錄,執行 gradlew -version
或者 gradlew -v
命令查看當前工程 gradle 版本。
根據 gradle 版本進行以下配置:
在 app 模塊下的 build.gradle
添加下面的配置:
dependencies { compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}' annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}' }
在 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}' }
注意:註解的方法不能是 private 的。
註解 | 是否必須 | 描述 |
---|---|---|
@RuntimePermissions |
✓ | 註冊一個 Activity 或 Fragment 用於處理權限 |
@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(); } }
註解寫好後,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 能夠參考這個開源項目。
<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 的輔助插件,支持自動生成權限檢查相關代碼。
項目地址:https://github.com/shiraji/permissions-dispatcher-plugin
安裝說明:Android Studio 中打開 Setting,
Plugins ——> Browse repositories...
搜索PermissionsDispatcher plugin
,點 Install 下載安裝,安裝完成後重啓生效。
image
使用說明:
使用過程當中發現有兩個小問題須要注意一下:
onRequestPermissionsResult
方法也會被自動添加屢次Build ——> Make Module ***
相對快些做者:linchaolong 連接:https://www.jianshu.com/p/64e7334cde11 來源:簡書 簡書著做權歸做者全部,任何形式的轉載都請聯繫做者得到受權並註明出處。