PermissionsDispatcher是一個基于注解肯夏、幫助開發(fā)者簡單處理Android 6.0系統(tǒng)中的運行時權(quán)限的開源庫谐岁。避免了開發(fā)者編寫大量繁瑣的樣板代碼趴久。
開源地址:https://github.com/hotchemi/PermissionsDispatcher
文檔介紹:http://hotchemi.github.io/PermissionsDispatcher/
下面詳細介紹一下如何在Android Studio上使用該開源庫运提。
1、添加依賴
首先在項目工程下的build.gradle
文件中加入對maven倉庫依賴引入的支持塘辅。
allprojects {
repositories {
jcenter()
mavenCentral()
}
}
之后在module下的build.gradle
文件中添加兩項依賴:
compile 'com.github.hotchemi:permissionsdispatcher:2.3.1'
annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.1'
并將targetSdkVersion
設(shè)為23,即:targetSdkVersion 23
2皆撩、在Activity或Fragment中使用
注解列表:
Annotation | Required | Description |
---|---|---|
@RuntimePermissions |
? | 注解在其內(nèi)部需要使用運行時權(quán)限的Activity或Fragment上 |
@NeedsPermission |
? | 注解在需要調(diào)用運行時權(quán)限的方法上扣墩,當用戶給予權(quán)限時會執(zhí)行該方法 |
@OnShowRationale |
注解在用于向用戶解釋為什么需要調(diào)用該權(quán)限的方法上,只有當?shù)谝淮握埱髾?quán)限被用戶拒絕扛吞,下次請求權(quán)限之前會調(diào)用 | |
@OnPermissionDenied |
注解在當用戶拒絕了權(quán)限請求時需要調(diào)用的方法上 | |
@OnNeverAskAgain |
注解在當用戶選中了授權(quán)窗口中的不再詢問復(fù)選框后并拒絕了權(quán)限請求時需要調(diào)用的方法呻惕,一般可以向用戶解釋為何申請此權(quán)限,并根據(jù)實際需求決定是否再次彈出權(quán)限請求對話框 |
注意:被注解的方法不能是私有方法滥比。
只有@RuntimePermissions
和@NeedsPermission
是必須的亚脆,其余注解均為可選。當使用了@RuntimePermissions
和@NeedsPermission
之后盲泛,需要點擊菜單欄中Build
菜單下的Make Project
濒持,或者按快捷鍵Ctrl + F9
編譯整個項目,編譯器會在app\build\intermediates\classes\debug
目錄下與被注解的Activity同一個包下生成一個輔助類寺滚,名稱為被注解的Activity名稱+PermissionsDispatcher.class
弥喉,如圖所示:
接下來可以調(diào)用輔助類里面的方法完成應(yīng)用的權(quán)限請求了。
在需要調(diào)用權(quán)限的位置調(diào)用輔助類里面的xxxWithCheck
方法玛迄,xxx
是被@NeedsPermission
注解的方法名由境。如:
MainActivityPermissionsDispatcher.showCameraWithCheck(this);
之后,還需要重寫該Activity的onRequestPermissionsResult()
方法,其方法內(nèi)調(diào)用輔助類的onRequestPermissionsResult()
方法虏杰,如下:
@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);
}
完整的MainActivity
如下所示讥蟆。
- MainActivity.java
@RuntimePermissions
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button_camera).setOnClickListener(this);
findViewById(R.id.button_contacts).setOnClickListener(this);
}
@Override
public void onClick(@NonNull View v) {
switch (v.getId()) {
case R.id.button_camera:
// NOTE: delegate the permission handling to generated method
MainActivityPermissionsDispatcher.showCameraWithCheck(this);
break;
case R.id.button_contacts:
// NOTE: delegate the permission handling to generated method
MainActivityPermissionsDispatcher.showContactsWithCheck(this);
break;
}
}
@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);
}
@NeedsPermission(Manifest.permission.CAMERA)
void showCamera() {
// NOTE: Perform action that requires the permission. If this is run by PermissionsDispatcher, the permission will have been granted
getSupportFragmentManager().beginTransaction()
.replace(R.id.sample_content_fragment, CameraPreviewFragment.newInstance())
.addToBackStack("camera")
.commitAllowingStateLoss();
}
@NeedsPermission({Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS})
void showContacts() {
// NOTE: Perform action that requires the permission.
// If this is run by PermissionsDispatcher, the permission will have been granted
getSupportFragmentManager().beginTransaction()
.replace(R.id.sample_content_fragment, ContactsFragment.newInstance())
.addToBackStack("contacts")
.commitAllowingStateLoss();
}
@OnShowRationale(Manifest.permission.CAMERA)
void showRationaleForCamera(PermissionRequest request) {
// NOTE: Show a rationale to explain why the permission is needed, e.g. with a dialog.
// Call proceed() or cancel() on the provided PermissionRequest to continue or abort
showRationaleDialog(R.string.permission_camera_rationale, request);
}
@OnShowRationale({Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS})
void showRationaleForContact(PermissionRequest request) {
// NOTE: Show a rationale to explain why the permission is needed, e.g. with a dialog.
// Call proceed() or cancel() on the provided PermissionRequest to continue or abort
showRationaleDialog(R.string.permission_contacts_rationale, request);
}
@OnPermissionDenied(Manifest.permission.CAMERA)
void onCameraDenied() {
// NOTE: Deal with a denied permission, e.g. by showing specific UI
// or disabling certain functionality
Toast.makeText(this, R.string.permission_camera_denied, Toast.LENGTH_SHORT).show();
}
@OnNeverAskAgain(Manifest.permission.CAMERA)
void onCameraNeverAskAgain() {
Toast.makeText(this, R.string.permission_camera_never_askagain, Toast.LENGTH_SHORT).show();
}
public void onBackClick(View view) {
getSupportFragmentManager().popBackStack();
}
private void showRationaleDialog(@StringRes int messageResId, final PermissionRequest request) {
new AlertDialog.Builder(this)
.setPositiveButton("允許", new DialogInterface.OnClickListener() {
@Override
public void onClick(@NonNull DialogInterface dialog, int which) {
request.proceed();
}
})
.setNegativeButton("拒絕", new DialogInterface.OnClickListener() {
@Override
public void onClick(@NonNull DialogInterface dialog, int which) {
request.cancel();
}
})
.setCancelable(false)
.setMessage(messageResId)
.show();
}
}
3、附:危險權(quán)限和權(quán)限組列表
Android官方文檔:https://developer.android.com/guide/topics/security/permissions.html#normal-dangerous
摘錄如下:
權(quán)限組 | 權(quán)限 |
---|---|
CALENDAR | READ_CALENDAR WRITE_CALENDAR |
CAMERA | CAMERA |
CONTACTS | READ_CONTACTS WRITE_CONTACTS GET_ACCOUNTS |
LOCATION | ACCESS_FINE_LOCATION ACCESS_COARSE_LOCATION |
PHONE | READ_PHONE_STATE CALL_PHONE READ_CALL_LOG WRITE_CALL_LOG ADD_VOICEMAIL USE_SIP PROCESS_OUTGOING_CALLS |
SENSORS | BODY_SENSORS |
SMS | SEND_SMS RECEIVE_SMS READ_SMS RECEIVE_WAP_PUSH RECEIVE_MMS |
STORAGE | READ_EXTERNAL_STORAGE WRITE_EXTERNAL_STORAGE |