现在有Rxjava的权限处理方案了,我两年前写的这个就不用啦,哈哈哈
===================================================================================
虽然已经有很多关于Android6.0权限处理的方案和帖子甚至框架,但是自己真正动手实现的才是最踏实的!!闲话少说,开车!
楼主主要用了两个类,BaseActivity和PermissionPool
**BaseActivity:**所有Activity的父类
**功能:**让所有继承自它的Activity在需要进行权限处理的时候都只需要调用一个方法(连判断都不用),然后重写一个成功方法和一个失败方法,在方法里做自己的逻辑就行了。是不是很清晰明了??
实现:
public class BaseActivity extends AppCompatActivity {
/**
* android6.0权限处理
* @param code 权限标记Code
* @param permissionName 权限名称
*/
public void permissionDispose(@PermissionPool.PermissionCode int code,@PermissionPool.PermissionName String permissionName){
if(ContextCompat.checkSelfPermission(this, permissionName)!= PackageManager.PERMISSION_GRANTED){
//没有权限,开始申请
ActivityCompat.requestPermissions(this,new String[]{permissionName},code);
}else{
//有权限
onAccreditSucceed(code);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
//授权成功
onAccreditSucceed(requestCode);
}else if(grantResults[0]==PackageManager.PERMISSION_DENIED){
//授权失败
onAccreditFailure (requestCode);
}
}
/**
* 有授权执行的方法(子类重写)
*/
public void onAccreditSucceed(int requestCode) {
}
/**
* 没有授权执行的方法(子类重写)
*/
public void onAccreditFailure(int requestCode) {
}
}
permissionDispose()方法是供子Activity直接调用的,参数1是一个权限标记常量,参数2是权限名称(2个参数都经过PermissionPool类约束的)先判断权限是否授权,没有就去申请,有就直接调用方法onAccreditSucceed(),并把code标记传过去。
没有权限就去申请权限,之后在回调方法onRequestPermissionsResult()里再判断是否授权成功,没有执行onAccreditFailure();有执行onAccreditSucceed();
好啦,BastActivity里的代码就这么多,一共4个方法,简单吧!!只有3个方法子Activity能用到,O(∩_∩)O哈哈~
**PermissionPool:**就理解成一个常量类吧,可以直接复制用哟 O(∩_∩)O
**功能:**约束上面BaseActivity.permissionDispose()里的参数,方便记忆且调用的时候非常方便还有提示!如果闲麻烦这个类是可以不用的,就是不约束permissionDispose()里的参数,个人觉得还是用比较好,一劳永逸!!
实现:
public class PermissionPool {
//联系人相关组
public static final int WRITE_CONTACTS = 0;
public static final int GET_ACCOUNTS = 1;
public static final int READ_CONTACTS = 2;
// 电话相关组
public static final int READ_CALL_LOG = 3;
public static final int READ_PHONE_STATE = 4;
public static final int CALL_PHONE = 5;
public static final int WRITE_CALL_LOG = 6;
public static final int USE_SIP = 7;
public static final int PROCESS_OUTGOING_CALLS = 8;
public static final int ADD_VOICEMAIL = 9;
//日历相关组
public static final int READ_CALENDAR = 10;
public static final int WRITE_CALENDAR = 11;
//摄像头相关组
public static final int CAMERA = 12;
//传感器相关组
public static final int BODY_SENSORS = 13;
public static final int ACCESS_FINE_LOCATION = 14;
public static final int ACCESS_COARSE_LOCATION = 15;
//存储相关组
public static final int READ_EXTERNAL_STORAGE = 16;
public static final int WRITE_EXTERNAL_STORAGE = 17;
//麦克风相关组
public static final int RECORD_AUDIO = 18;
//短信相关组
public static final int READ_SMS = 19;
public static final int RECEIVE_WAP_PUSH = 20;
public static final int RECEIVE_MMS = 21;
public static final int RECEIVE_SMS = 22;
public static final int SEND_SMS = 23;
@IntDef({WRITE_CONTACTS,
GET_ACCOUNTS,
READ_CONTACTS,
READ_CALL_LOG,
READ_PHONE_STATE,
CALL_PHONE,
WRITE_CALL_LOG,
USE_SIP,
PROCESS_OUTGOING_CALLS,
ADD_VOICEMAIL,
READ_CALENDAR,
WRITE_CALENDAR,
CAMERA,
BODY_SENSORS,
ACCESS_FINE_LOCATION,
ACCESS_COARSE_LOCATION,
READ_EXTERNAL_STORAGE,
WRITE_EXTERNAL_STORAGE,
RECORD_AUDIO,
READ_SMS,
RECEIVE_WAP_PUSH,
RECEIVE_MMS,
RECEIVE_SMS,
SEND_SMS})
@Retention(RetentionPolicy.SOURCE)
public @interface PermissionCode {
}
@StringDef({
//联系人相关组
Manifest.permission.WRITE_CONTACTS,
Manifest.permission.GET_ACCOUNTS,
Manifest.permission.READ_CONTACTS,
// 电话相关组
Manifest.permission.READ_CALL_LOG,
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.CALL_PHONE,
Manifest.permission.WRITE_CALL_LOG,
Manifest.permission.USE_SIP,
Manifest.permission.PROCESS_OUTGOING_CALLS,
Manifest.permission.ADD_VOICEMAIL,
//日历相关组
Manifest.permission.READ_CALENDAR,
Manifest.permission.WRITE_CALENDAR,
//摄像头相关组
Manifest.permission.CAMERA,
//传感器相关组
Manifest.permission.BODY_SENSORS,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
//存储相关组
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
//麦克风相关组
Manifest.permission.RECORD_AUDIO,
//短信相关组
Manifest.permission.READ_SMS,
Manifest.permission.RECEIVE_WAP_PUSH,
Manifest.permission.RECEIVE_MMS,
Manifest.permission.RECEIVE_SMS,
Manifest.permission.SEND_SMS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface PermissionName {
}
}
需要权限处理的Activity调用:
就以打开摄像头为例:只需两步
1、先开始权限处理
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//直接调用父类的权限处理方法,不用判读是否有该权限,因为父类已经判断了
permissionDispose(PermissionPool.CAMERA, Manifest.permission.CAMERA);
}
});
2、重写有权限和无权限的两个方法
@Override
public void onAccreditSucceed(int requestCode) {
switch (requestCode) {
case PermissionPool.CAMERA:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//这里可能会编译报错,IDE提示你应该处理权限问题,然而我们已经处理了,所以直接运行不用管它
startActivityForResult(intent, 0);
break;
}
}
@Override
public void onAccreditFailure(int requestCode) {
switch (requestCode) {
case PermissionPool.CAMERA:
Toast.makeText(this, "相机授权失败,无法继续操作", Toast.LENGTH_SHORT).show();
break;
}
}
需要注意的点:
1.所有的权限都还是要在AndroidManifest.xml里声明,因为要兼容6.0以下版本
2.调用permissionDispose()时第一个参数和第二个参数的名称应该对应,不然回调会搞乱!!这样比较好:PermissionPool.CAMERA和new String[]{Manifest.permission.CAMERA}