Android 6.0动态权限介绍

2018-08-30  本文已影响0人  左大人

image.png

使用权限

Android应用默认情况未关联任何权限,这就意味着它无法执行对用户体验或设备上的数据产生不利影响的操作。要使用受保护的设备功能,必须在Manifest中包含<uses-permission>标记。

使用权限分为2个级别:

危险权限列表

image.png

动态请求权限

此处针对Android6.0以上版本。
如果需要用到危险权限,例如拍照、存储文件、读取文件等操作,就需要在代码中动态申请该权限。

有两种申请方式:

1. RxPermissions

这是一种很简便的方式,并且可以结合RxJava一起使用,具体使用方式网上有很多介绍,此处就简单说一下。
RxPermissions地址:https://github.com/tbruyelle/RxPermissions
在模块build.gradle文件中添加依赖:

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

创建一个RxPermissions对象:

val rxPermissions = RxPermissions(this)

this表示FragmentActivity或者Fragment,RxPermissions的构造方法如下:

public RxPermissions(@NonNull FragmentActivity activity) {
    this.mRxPermissionsFragment = this.getLazySingleton(activity.getSupportFragmentManager());
}

public RxPermissions(@NonNull Fragment fragment) {
    this.mRxPermissionsFragment = this.getLazySingleton(fragment.getChildFragmentManager());
}

申请权限,一次可申请一个或多个:

rxPermissions.requestEach(Manifest.permission.CAMERA, Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.CALL_PHONE)
            .subscribe {
                when {
                    it.granted -> { //授权成功
                        LogUtil.i("zf_tag", it.name + " granted success")
                    }
                    it.shouldShowRequestPermissionRationale -> { //授权失败,可再次弹框请求
                        LogUtil.i("zf_tag", it.name + " denied permission with ask again")
                    }
                    else -> {//授权失败,不能再次请求,只能到系统设置页面去修改权限
                        LogUtil.i("zf_tag", it.name + " denied permission without ask again")
                    }
                }
            }

使用RxPermissions请求权限很简单吧。RxPermissions有几个优点:

但使用过程中也有一些受限制的地方。
初始化RxPermissions对象依赖于Activity和Fragment,如果工具类中涉及到权限请求,不好判断。
下面提供一个判断是否具有某个权限的判断方法,可用于非Activity、Fragment的判断:

/**
 * 判断应用是否具有某个权限
 */
public static boolean isPermissionGranted(Context context, String permission) {
    if (context == null) {
        return false;
    }
    // For Android < Android M, self permissions are always granted.
    boolean result = true;

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        if (DeviceUtil.getTargetSdkVersion(context) >= Build.VERSION_CODES.M) {
            // targetSdkVersion >= Android M, we can
            // use Context#checkSelfPermission
            result = context.checkSelfPermission(permission)
                    == PackageManager.PERMISSION_GRANTED;
        } else {
            // targetSdkVersion < Android M, we have to use PermissionChecker
            result = PermissionChecker.checkSelfPermission(context, permission)
                    == PermissionChecker.PERMISSION_GRANTED;
        }
    }

    return result;
}

2. 系统requestPermissions方法

通过系统方法requestPermissions方法请求危险权限,代码如下:

private fun requestPermissions() {
   ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA, Manifest.permission.READ_PHONE_STATE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.CALL_PHONE), 100)
}

Activity的回调方法onRequestPermissionsResult方法可以获取请求结果:

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

请求的时候传入一个权限数组,回调方法返回一个结果数组,根据结果数组判断权限是否请求成功。

总结

对比RxPermissions和系统的requestPermissions方法,明显RxPermissions操作更加简单,而且不用区分Android系统版本。所以实际项目中推荐使用RxPermissions方式。

上一篇下一篇

猜你喜欢

热点阅读