PermissionsDispatcher2.3.2使用
Android6.0權(quán)限官網(wǎng)
https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html?hl=zh-cn
系統(tǒng)權(quán)限:
https://developer.android.com/training/permissions/index.html?hl=zh-cn
權(quán)限的最佳做法:
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)當(dāng)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)當(dāng)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只介紹幾個(gè)注解,保持其通用API簡潔:
注:帶注釋的方法一定不能private。
注解 | 需要 | 描述 |
---|---|---|
@RuntimePermissions | ? | 在Activity或者Fragment中需要添加,來處理權(quán)限的問題 |
@NeedsPermission | ? | 注釋其執(zhí)行需要一個(gè)或多個(gè)許可的作用的方法(當(dāng)用戶授予了權(quán)限之后,會(huì)調(diào)用使用此注解的方法) |
@OnShowRationale | 注釋這解釋了為什么需要許可/秒/方法。它通過在一個(gè)PermissionRequest可用于繼續(xù)或中止在用戶輸入的當(dāng)前的許可請求對象 | |
@OnPermissionDenied | 注釋這是調(diào)用的方法痕貌,如果用戶不授予的權(quán)限 | |
@OnNeverAskAgain | 注釋如果用戶選擇讓設(shè)備“不再詢問”有關(guān)許可被調(diào)用的方法 |
具體使用如下:
@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.自動(dòng)生成的類
Activity繼承了AppCompatActivity,是的糠排,如果使用PermissionsDispatcher進(jìn)行權(quán)限管理舵稠,那么Activity就要繼承AppCompatActivity。這就要使用到了兼容包里的類了入宦。同樣此時(shí)相應(yīng)Activity中使用的主題哺徊,也需要進(jìn)行修改,修改成相應(yīng)兼容包里的主題乾闰。
在編譯時(shí)唉工,PermissionsDispatcher產(chǎn)生的一類MainActivityPermissionsDispatcher([活動(dòng)名稱] + PermissionsDispatcher),您可以使用安全地訪問這些許可保護(hù)的方法汹忠。
MainActivityPermissionsDispatcher需要自己編譯才會(huì)有:
@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、在注解的時(shí)候添加sdk版本控制
@RuntimePermissions
public class MainActivity extends AppCompatActivity {
@NeedsPermission(value = Manifest.permission.WRITE_EXTERNAL_STORAGE, maxSdkVersion = 18)
void getStorage() {
// ...
}
}
使用步驟:
一宽菜、在Manifest中添加權(quán)限
<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);
}
/**
* 顯示相機(jī)權(quán)限
*/
@NeedsPermission(Manifest.permission.CAMERA)
void showCamera() {//處理當(dāng)用戶允許該權(quán)限時(shí)需要處理的方法
getSupportFragmentManager().beginTransaction()
.replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
.addToBackStack("camera")
.commitAllowingStateLoss();
}
@OnShowRationale(Manifest.permission.CAMERA)
void showRationaleForCamera(final PermissionRequest request) {// 提示用戶權(quán)限使用的對話框
new AlertDialog
.Builder(this)
.setMessage("是否打開權(quán)限")
.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();
}
/**
* 如果用戶拒絕該權(quán)限執(zhí)行的方法
*/
@OnPermissionDenied(Manifest.permission.CAMERA)
void showDeniedForCamera() {
Toast.makeText(this, "獲取權(quán)限失敗", Toast.LENGTH_SHORT).show();
}
@OnNeverAskAgain(Manifest.permission.CAMERA)
void showNeverAskForCamera() {
Toast.makeText(this, "再次獲取權(quán)限", Toast.LENGTH_SHORT).show();
}
三、重寫回調(diào)方法铅乡,并且使用MainActivityPermissionsDispatcher(此方法編譯生成【Activity】+PermissionsDispatcher)
/**
* 權(quán)限請求回調(diào)继谚,提示用戶之后,用戶點(diǎn)擊“允許”或者“拒絕”之后調(diào)用此方法
*
* @param requestCode 定義的權(quán)限編碼
* @param permissions 權(quán)限名稱
* @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, "相機(jī)");
// 默認(rèn)是沒有此類的阵幸,需要編譯下才會(huì)有此類
MainActivityPermissionsDispatcher.showCameraWithCheck(this);
break;
}
}
注意
- 使用到的權(quán)限需要在Mnifest里面注冊
- PermissionsDispatcher依賴于support-v4由默認(rèn)庫花履,以便能夠使用一些權(quán)限compat的類。
- 需要添加support-v13庫一起PermissionsDispatcher在您的項(xiàng)目挚赊,它將使原生片段支持
原生6.0權(quán)限使用
Android 6.0 變更
另請參閱
Android 6.0 API 概覽
Android 6.0(API 級(jí)別 23)除了提供諸多新特性和功能外诡壁,還對系統(tǒng)和 API 行為做出了各種變更。
如果您之前發(fā)布過 Android 應(yīng)用荠割,請注意您的應(yīng)用可能受到這些平臺(tái)變更的影響妹卿。
運(yùn)行時(shí)權(quán)限
此版本引入了一種新的權(quán)限模式,如今蔑鹦,用戶可直接在運(yùn)行時(shí)管理應(yīng)用權(quán)限夺克。這種模式讓用戶能夠更好地了解和控制權(quán)限,同時(shí)為應(yīng)用開發(fā)者精簡了安裝和自動(dòng)更新過程嚎朽。用戶可為所安裝的各個(gè)應(yīng)用分別授予或撤銷權(quán)限铺纽。
對于以 Android 6.0(API 級(jí)別 23)或更高版本為目標(biāo)平臺(tái)的應(yīng)用,請務(wù)必在運(yùn)行時(shí)檢查和請求權(quán)限哟忍。要確定您的應(yīng)用是否已被授予權(quán)限狡门,請調(diào)用新增的 checkSelfPermission()
方法陷寝。要請求權(quán)限,請調(diào)用新增的 [requestPermissions()](https://developer.android.com/reference/android/app/Activity.html?hl=zh-cn#requestPermissions(java.lang.String[], int))
方法融撞。即使您的應(yīng)用并不以 Android 6.0(API 級(jí)別 23)為目標(biāo)平臺(tái),您也應(yīng)該在新權(quán)限模式下測試您的應(yīng)用粗蔚。
使用步驟
1尝偎、在AndroidManifest文件中添加需要的權(quán)限。
這個(gè)步驟和我們之前的開發(fā)并沒有什么變化鹏控,試圖去申請一個(gè)沒有聲明的權(quán)限可能會(huì)導(dǎo)致程序崩潰致扯。
2、檢查權(quán)限
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
}else{
//
}
這里涉及到一個(gè)API当辐,ContextCompat.checkSelfPermission抖僵,主要用于檢測某個(gè)權(quán)限是否已經(jīng)被授予,方法返回值為PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED缘揪。當(dāng)返回DENIED就需要進(jìn)行申請授權(quán)了耍群。
3、申請授權(quán)
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
該方法是異步的找筝,第一個(gè)參數(shù)是Context蹈垢;第二個(gè)參數(shù)是需要申請的權(quán)限的字符串?dāng)?shù)組;第三個(gè)參數(shù)為requestCode袖裕,主要用于回調(diào)的時(shí)候檢測曹抬。可以從方法名requestPermissions以及第二個(gè)參數(shù)看出急鳄,是支持一次性申請多個(gè)權(quán)限的谤民,系統(tǒng)會(huì)通過對話框逐一詢問用戶是否授權(quán)。
4疾宏、處理權(quán)限申請回調(diào)
@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;
}
}
}
首先驗(yàn)證requestCode定位到你的申請张足,然后驗(yàn)證grantResults對應(yīng)于申請的結(jié)果,這里的數(shù)組對應(yīng)于申請時(shí)的第二個(gè)權(quán)限字符串?dāng)?shù)組坎藐。如果你同時(shí)申請兩個(gè)權(quán)限兢榨,那么grantResults的length就為2,分別記錄你兩個(gè)權(quán)限的申請結(jié)果顺饮。如果申請成功吵聪,就可以做你的事情了~
具體使用詳見demo,GitHub:https://github.com/huangshuyuan/PermissionsDispatcherDemo
參考文檔:http://blog.csdn.net/lmj623565791/article/details/50709663
補(bǔ)充
現(xiàn)在網(wǎng)上不少關(guān)于權(quán)限的庫兼雄,可以直接用的吟逝,在GitHub上搜索即可
https://github.com/search?o=desc&q=android+permission&s=stars&type=Repositories&utf8=%E2%9C%93
有興趣可以研究一下其他的庫,已經(jīng)把根據(jù)星級(jí)排名前幾名的粘貼出來了
PermissionsDispatcher https://github.com/hotchemi/PermissionsDispatcher
RxPermissions https://github.com/tbruyelle/RxPermissions
easypermissions https://github.com/googlesamples/easypermissions
Dexter https://github.com/Karumi/Dexter
PermissionHelper https://github.com/k0shk0sh/PermissionHelper
AndPermission https://github.com/yanzhenjie/AndPermission
我的博客:http://blog.csdn.net/Imshuyuan/article/details/64919365