android权限工具类封装,Android组件化架构 - 6. 权限管理

权限的目的

权限设立的目的是保护安全

权限机制

系统权限分三种:

Android所有者权限,即Android Rom开发权限;

Android Root权限,Linux系统中的最高用户权限;

Android 应用程序权限,应用开发者在项目的AndroidManifest中声明,然后由用户授权获取

(Android 应用程序权限分为两种,普通权限(不涉及用户隐私,系统自动授权)和敏感权限(涉及用户隐私,需要用户手动授权))

1. 原生运行时权限请求

工具类封装

/**

* @Author: LiuJinYang

* 运行时权限工具类

*/

public class LjyPermissionUtil {

private PermissionResultListener permissionResultListener;

private LjyPermissionUtil() {

}

public static LjyPermissionUtil getInstance() {

return PermissionUtilHolder.instancePermissionUtil;

}

private static class PermissionUtilHolder {

private static final LjyPermissionUtil instancePermissionUtil

= new LjyPermissionUtil();

}

/**

* 判断当前应用是否有指定权限,运行时权限的检测

*/

public boolean hasPermissions(Context context, String[] permissions) {

if (permissions == null || permissions.length == 0) {

return true;

}

boolean ifSdk = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;

for (String permission : permissions) {

if (ifSdk && !hasPermission(context, permission)) {

return false;

}

}

return true;

}

private boolean hasPermission(Context context, String permission) {

return ActivityCompat.checkSelfPermission(context, permission)

== PackageManager.PERMISSION_GRANTED;

}

/**

* 动态申请指定权限,配合hasPermission使用,

* 注意在使用的activity中调用onRequestPermissionsResult权限申请结果的回调

*

* @param activity

* @param permissions

* @param requestCode

*/

public void requestPermission(final Activity activity, final String[] permissions,

final int requestCode, final PermissionResultListener permissionResultListener) {

this.permissionResultListener = permissionResultListener;

ActivityCompat.requestPermissions(activity, permissions, requestCode);

}

/**

* 申请权限的结果回调,需要在Activity的onRequestPermissionsResult中调用

*

* @param grantResults

*/

public void onPermissionResult(Activity activity, final int requestCode,

String[] permissions, int[] grantResults) {

boolean hasPermission = true;

List deniedList = new ArrayList<>();

List cancelList = new ArrayList<>();

for (int i = 0; i < grantResults.length; i++) {

boolean isAllow = grantResults[i] == PackageManager.PERMISSION_GRANTED;

hasPermission &= isAllow;

if (!isAllow) {

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M

|| !activity.shouldShowRequestPermissionRationale(permissions[i])) {

deniedList.add(permissions[i]);

} else {

cancelList.add(permissions[i]);

}

}

}

if (permissionResultListener != null) {

if (hasPermission) {

permissionResultListener.onSuccess(requestCode);

} else {

if (deniedList.size() > 0) {

permissionResultListener.onDenied(deniedList);

}

if (cancelList.size() > 0) {

permissionResultListener.onCancel(cancelList);

}

}

}

}

/**

* 权限申请结果的回调接口

*/

public interface PermissionResultListener {

/**

* 申请成功

*/

void onSuccess(final int requestCode);

/**

* 拒绝的权限集合(不在弹框提醒)

*/

void onDenied(@NonNull List deniedList);

/**

* 取消的权限集合

*/

void onCancel(@NonNull List cancelList);

}

}

工具类的使用

//baseActivity的onRequestPermissionsResult中

open class BaseActivity : AppCompatActivity() {

override fun onRequestPermissionsResult(requestCode: Int,

permissions: Array, grantResults: IntArray) {

if (grantResults.isNotEmpty()) {

LjyPermissionUtil.getInstance().onPermissionResult(this,

requestCode, permissions, grantResults)

}

}

}

class PermissionActivity : BaseActivity() {

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_permission)

}

fun onBtnClick(view: View) {

when (view.id) {

//原生获取运行时权限

R.id.button_perm_1 -> requestPermission()

}

}

private fun requestPermission() {

val permissions = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE,

Manifest.permission.CALL_PHONE, Manifest.permission.CAMERA)

if (LjyPermissionUtil.getInstance().hasPermissions(this@PermissionActivity, permissions)) {

printFileName()

} else {

val mRequestCode=1002

LjyPermissionUtil.getInstance().requestPermission(

this@PermissionActivity,

permissions,

mRequestCode,

object : LjyPermissionUtil.PermissionResultListener {

override fun onSuccess(requestCode: Int) {

if (requestCode == mRequestCode) {

printFileName()

}

}

override fun onDenied(deniedList: MutableList) {

LjyToastUtil.toast(this@PermissionActivity,

"权限被拒绝,将导致APP无法正常使用,请前往设置中修改")

for (it in deniedList) {

LjyLogUtil.d("deniedList:$it")

}

}

override fun onCancel(cancelList: MutableList) {

LjyToastUtil.toast(this@PermissionActivity, "取消了权限申请")

for (it in cancelList) {

LjyLogUtil.d("failList:$it")

}

}

}

)

}

}

private fun printFileName() {

LjyLogUtil.d("操作文件...")

}

}

2. RxPermission

还有一些比较常用的权限请求框架,如RxPermission

//rxPermissionss的使用

//1. build.gradle中添加依赖

allprojects {

repositories {

...

maven { url 'https://jitpack.io' }

}

}

dependencies {

implementation 'com.github.tbruyelle:rxpermissions:0.12'

}

//注意:最新版rxpermission需要配合RxJava3使用

//rxjava3

implementation 'io.reactivex.rxjava3:rxjava:3.0.4'

implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'

//2.调用

//所有权限统一结果

new RxPermissions(this)

.request(Manifest.permission.READ_EXTERNAL_STORAGE,

Manifest.permission.CALL_PHONE, Manifest.permission.CAMERA)

.subscribe(accept -> {

if (accept) {

LjyLogUtil.d("允许了权限申请");

} else {

LjyLogUtil.d("拒绝了权限申请");

}

});

//将权限申请结果逐一返回

new RxPermissions(this)

.requestEach(Manifest.permission.READ_EXTERNAL_STORAGE,

Manifest.permission.CALL_PHONE, Manifest.permission.CAMERA)

.subscribe(permission -> {

// will emit 2 Permission objects

LjyLogUtil.d(permission.toString());

if (permission.granted) {

// `permission.name` is granted !

LjyLogUtil.d("允许了权限申请:" + permission.name);

} else if (permission.shouldShowRequestPermissionRationale) {

// Denied permission without ask never again

LjyLogUtil.d("取消了权限申请:" + permission.name);

} else {

// Denied permission with ask never again

// Need to go to the settings

LjyLogUtil.d("权限被拒绝,将导致APP无法正常使用,请前往设置中修改:" + permission.name);

}

});

3. RxPermissions原理

新建RxPermissions类的时候,框架会悄悄的新建一个RxPermissionsFragment类,

也就是说框架在内部封装了一个没有界面的fragment,

这样做的好处是请求权限的回调可以在Fragment中实现,不需要用户再去调用onRequestPermissionsResult

我是今阳,如果想要进阶和了解更多的干货,欢迎关注公众号”今阳说“接收我的最新文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值