PermissionsDispatcher2.3.2使用
Android6.0權限官網
https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html?hl=zh-cn
系統權限:
https://developer.android.com/training/permissions/index.html?hl=zh-cn
權限的最佳做法:
https://developer.android.com/training/permissions/best-practices.html?hl=zh-cn#testing
該庫的github地址
https://github.com/hotchemi/PermissionsDispatcher

Gradle配置
使用PermissionsDispatcher,需要在project的 build.gradle中添加
(1)當Studio的版本在2.2之上
在app module中的build.gradle中添加:
dependencies {
compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}'
annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}'
}
目前${latest.version}
最新的是2.3.2。
(2)當Studio的版低於2.2
在工程目錄下build.gradle 文件中添加:
buildscript {
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
然后在app module中的build.gradle中添加:(必須在app module中添加)
apply plugin: 'android-apt'
dependencies {
compile 'com.github.hotchemi:permissionsdispatcher:${latest.version}'
apt 'com.github.hotchemi:permissionsdispatcher-processor:${latest.version}'
}
用法:
1.注解
PermissionsDispatcher只介紹幾個注解,保持其通用API簡潔:
注:帶注釋的方法一定不能private。
注解 | 需要 | 描述 |
---|---|---|
@RuntimePermissions | ✓ | 在Activity或者Fragment中需要添加,來處理權限的問題 |
@NeedsPermission | ✓ | 注釋其執行需要一個或多個許可的作用的方法(當用戶授予了權限之后,會調用使用此注解的方法) |
@OnShowRationale | 注釋這解釋了為什么需要許可/秒/方法。它通過在一個PermissionRequest可用於繼續或中止在用戶輸入的當前的許可請求對象 | |
@OnPermissionDenied | 注釋這是調用的方法,如果用戶不授予的權限 | |
@OnNeverAskAgain | 注釋如果用戶選擇讓設備“不再詢問”有關許可被調用的方法 |
具體使用如下:
@RuntimePermissions
public class MainActivity extends AppCompatActivity {
@NeedsPermission(Manifest.permission.CAMERA)
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.自動生成的類
Activity繼承了AppCompatActivity,是的,如果使用PermissionsDispatcher進行權限管理,那么Activity就要繼承AppCompatActivity。這就要使用到了兼容包里的類了。同樣此時相應Activity中使用的主題,也需要進行修改,修改成相應兼容包里的主題。
在編譯時,PermissionsDispatcher產生的一類MainActivityPermissionsDispatcher([活動名稱] + PermissionsDispatcher),您可以使用安全地訪問這些許可保護的方法。
MainActivityPermissionsDispatcher需要自己編譯才會有:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button_camera).setOnClickListener(v -> {
// NOTE: delegate the permission handling to generated method
MainActivityPermissionsDispatcher.showCameraWithCheck(this);
});
findViewById(R.id.button_contacts).setOnClickListener(v -> {
// NOTE: delegate the permission handling to generated method
MainActivityPermissionsDispatcher.showContactsWithCheck(this);
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// NOTE: delegate the permission handling to generated method
MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
添加SDK支持版本的兩種方式:
- 1、AndroidManifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18" />
- 2、在注解的時候添加sdk版本控制
@RuntimePermissions
public class MainActivity extends AppCompatActivity {
@NeedsPermission(value = Manifest.permission.WRITE_EXTERNAL_STORAGE, maxSdkVersion = 18)
void getStorage() {
// ...
}
}
使用步驟:
一、在Manifest中添加權限
<uses-permission android:name="android.permission.CAMERA" />
二、在Activity中添加注解
@RuntimePermissions
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
}
/**
* 顯示相機權限
*/
@NeedsPermission(Manifest.permission.CAMERA)
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("是否打開權限")
.setPositiveButton("允許", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
request.proceed();
}
})
.setNegativeButton("拒絕", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
request.cancel();
}
})
.show();
}
/**
* 如果用戶拒絕該權限執行的方法
*/
@OnPermissionDenied(Manifest.permission.CAMERA)
void showDeniedForCamera() {
Toast.makeText(this, "獲取權限失敗", Toast.LENGTH_SHORT).show();
}
@OnNeverAskAgain(Manifest.permission.CAMERA)
void showNeverAskForCamera() {
Toast.makeText(this, "再次獲取權限", Toast.LENGTH_SHORT).show();
}
三、重寫回調方法,並且使用MainActivityPermissionsDispatcher(此方法編譯生成【Activity】+PermissionsDispatcher)
/**
* 權限請求回調,提示用戶之后,用戶點擊“允許”或者“拒絕”之后調用此方法
*
* @param requestCode 定義的權限編碼
* @param permissions 權限名稱
* @param grantResults 允許/拒絕
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
MainActivityPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
}
@OnClick({R.id.button_camera, R.id.button_contacts})
public void onClick(View view) {
switch (view.getId()) {
case R.id.button_camera:
// show(this, "相機");
// 默認是沒有此類的,需要編譯下才會有此類
MainActivityPermissionsDispatcher.showCameraWithCheck(this);
break;
}
}
注意
- 使用到的權限需要在Mnifest里面注冊
- PermissionsDispatcher依賴於support-v4由默認庫,以便能夠使用一些權限compat的類。
- 需要添加support-v13庫一起PermissionsDispatcher在您的項目,它將使原生片段支持
原生6.0權限使用
Android 6.0 變更
Android 6.0(API 級別 23)除了提供諸多新特性和功能外,還對系統和 API 行為做出了各種變更。
如果您之前發布過 Android 應用,請注意您的應用可能受到這些平台變更的影響。
運行時權限
此版本引入了一種新的權限模式,如今,用戶可直接在運行時管理應用權限。這種模式讓用戶能夠更好地了解和控制權限,同時為應用開發者精簡了安裝和自動更新過程。用戶可為所安裝的各個應用分別授予或撤銷權限。
對於以 Android 6.0(API 級別 23)或更高版本為目標平台的應用,請務必在運行時檢查和請求權限。要確定您的應用是否已被授予權限,請調用新增的 checkSelfPermission()
方法。要請求權限,請調用新增的 requestPermissions()
方法。即使您的應用並不以 Android 6.0(API 級別 23)為目標平台,您也應該在新權限模式下測試您的應用。
使用步驟
1、在AndroidManifest文件中添加需要的權限。
這個步驟和我們之前的開發並沒有什么變化,試圖去申請一個沒有聲明的權限可能會導致程序崩潰。
2、檢查權限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
}else{
//
}
這里涉及到一個API,ContextCompat.checkSelfPermission,主要用於檢測某個權限是否已經被授予,方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。當返回DENIED就需要進行申請授權了。
3、申請授權
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
該方法是異步的,第一個參數是Context;第二個參數是需要申請的權限的字符串數組;第三個參數為requestCode,主要用於回調的時候檢測。可以從方法名requestPermissions以及第二個參數看出,是支持一次性申請多個權限的,系統會通過對話框逐一詢問用戶是否授權。
4、處理權限申請回調
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
}
}
首先驗證requestCode定位到你的申請,然后驗證grantResults對應於申請的結果,這里的數組對應於申請時的第二個權限字符串數組。如果你同時申請兩個權限,那么grantResults的length就為2,分別記錄你兩個權限的申請結果。如果申請成功,就可以做你的事情了~
具體使用詳見demo,GitHub:https://github.com/huangshuyuan/PermissionsDispatcherDemo
參考文檔:http://blog.csdn.net/lmj623565791/article/details/50709663
作者:流水潺湲
鏈接:http://www.jianshu.com/p/d299f22dfbdb
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
補充
現在網上不少關於權限的庫,可以直接用的,在GitHub上搜索即可
https://github.com/search?o=desc&q=android+permission&s=stars&type=Repositories&utf8=%E2%9C%93