一个垃圾的Android权限框架
学习和参考
- 简书 https://www.jianshu.com/p/2324a2bdb3d4
写在前头
今天突发奇想想要把Android申请权限的流程封装一下,为使得Android的权限申请更加容易一些。所以经过一番资料的查询和研究,做了一个小小的垃圾权限框架,不优雅也不高效。
项目信息
Github地址
https://github.com/littledavid-tech/GarbagePermission如何使用此框架
添加依赖
Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:
allprojects { repositories { ... maven { url 'https://www.jitpack.io' } } }
Step 2. Add the dependency
dependencies { implementation 'com.github.littledavid-tech:GarbagePermission:V1.0.1' }
调用代码
//Way 1GarbagePermission .with(this) .permissions(arrayOf( Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CALL_PHONE)) .callback(object : OnPermissionRequestListener { //当权限被同意的时候,此方法被调用 override fun onGranted(permission: String) { Log.e("TAG", "Granted") } //当权限被完全拒绝的时候(勾选了不再提醒复选框),此方法被调用 override fun onDenied(permission: String) { Log.e("TAG", "Denied") } //当权限被拒绝的时候但并非完全拒绝的时候,此方法被调用 override fun onRationale(permission: String) { Log.e("TAG", "Rationale") } }) .request()//Way 2GarbagePermission .with(this) .permissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE)) .callback(object : SimpleOnPermissionRequestListener() { override fun onGranted(permission: String) { Log.e("TAG", "Granted") } }) .request()
实现思路
只有在Android6.0以及之后的版本中,才需要进行动态权限的申请,在6.0之前是不用动态申请权限的。在申请权限的时候,我们习惯于在App首次运行的时候于启动界面将所有的界面都进行申请,并且在进行高危操作的使用,在进行检测权限,如果没有授权则进行权限的申请。
当我们申请权限后,我们必须调用Activity或者Fragment的 onRequestPermissionsResult
方法,所以我们的框架肯定是离不开Activity或者Fragment,又因为Activity比Fragment要独立,所以这里选择了Activity。
我们将所有请求权限的所有的业务逻辑都封装在一个Activity里面,当需要申请权限的时候就启动这个Activity进行权限的申请。
/** * 权限相关的回调接口 * The callback interface for request permission * @see SimpleOnPermissionRequestListener */interface OnPermissionRequestListener { /** * 当权限被同意的时候,此方法会被调用 * */ fun onGranted(permission: String) /** * 如果权限被完全拒绝(勾选了不再提示复选框) 此方法会被调用 * */ fun onDenied(permission: String) /** * 如果此方法没有被完全地拒绝(没有勾选不再提示复选框)此方法会被调用 * * */ fun onRationale(permission: String)}class PermissionActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_permission) //避免用户手动启动此Activity if (!intent.hasExtra(ACCESS_TOKEN)) { finish() } val permissions = intent.getStringArrayExtra("permissions") //判断SDK版本 if (Build.VERSION.SDK_INT >= 23) { requestPermissions(permissions, REQUEST_CODE) } } @TargetApi(23) override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (requestCode != REQUEST_CODE) { return } //根据选项的不同,调用不同的回调 for ((index, value) in permissions.withIndex()) { if (grantResults[index] == PackageManager.PERMISSION_GRANTED) {//接受 mPermissionCallback?.onGranted(value) } else if (shouldShowRequestPermissionRationale(value)) {//拒绝,但没有完全拒绝 mPermissionCallback?.onRationale(value) } else {//拒绝 mPermissionCallback?.onDenied(value) } } finish() } override fun onDestroy() { mPermissionCallback = null super.onDestroy() } companion object { private var mPermissionCallback: OnPermissionRequestListener? = null /** * 通过这个标志位来避免用户手动地打开此Activity,而非调用show方法 * */ private const val ACCESS_TOKEN = "token_permission" private const val REQUEST_CODE = 10086 /** * 显示此Activity * @param context 上下文 * @param permissions 需要进行请求的权限数组 * @param callback 处理权限问题的回调 * * @see OnPermissionRequestListener * */ fun show(context: Context, permissions: Array , callback: OnPermissionRequestListener?) { mPermissionCallback = callback val intent = Intent(context, PermissionActivity::class.java) intent.putExtra(ACCESS_TOKEN, ACCESS_TOKEN) intent.putExtra("permissions", permissions) context.startActivity(intent) } }}
但是这还不能够满足我们的要求,因为现在Activity还能够被用户感知到(废话,打开一个Activity,用户看不到就怪了),所以我们还需要对Activity进行一些特殊的设置。将Activity的背景等设置为不可见的状态。
为Activity设置上Style,在 Manifest
中
搞一个门面类
距离成功还差一点点,虽然我们通过上面建立的Activity就已经能够进行申请权限了,但是直接开启Activity请求权限太不雅观了啊 ? ,所以我们需要把Activity启动的过程封装一下,建立一个门面类来进行调用,假装高大上一点。
/** * GarbagePermission 权限请求框架 * */class GarbagePermission private constructor(private val context: Context) { private var mPermissions: Array? = null private var mCallback: OnPermissionRequestListener? = null /** * 设置你要请求的权限 * */ fun permissions(permissions: Array ): GarbagePermission { mPermissions = permissions return this } /** * 设置回调 * */ fun callback(onPermissionRequestListener: OnPermissionRequestListener): GarbagePermission { this.mCallback = onPermissionRequestListener return this } /** * 开始请求权限 * */ fun request() { if (mPermissions == null) { throw IllegalArgumentException("Please request permission") } if (Build.VERSION.SDK_INT >= 23) { PermissionActivity.show(context, mPermissions!!, mCallback) } } /** * GarbagePermission 权限请求框架 * */ companion object { fun with(context: Context): GarbagePermission { return GarbagePermission(context) } }}
总结
到这里,这个小小的框架就已经完成了,虽然网上已经有了很多的权限请求的框架,比我写的这个要优雅和高效很多并且代码量更少,但是,小的轮子还是非常值得我们自己动手造一造的。毕竟只写一写业务的代码进步是非常慢的,身为一个技术工作者,我们总要追寻更优雅的解决方案,OK到此结束,与诸君共勉。