Android6.0权限处理封装

更新 2019-04-13

现在有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}

你可能感兴趣的:(一棵树)