标签:name ica etc 授权 list lis lse 实现 manage
今天突发奇想想要把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 1
GarbagePermission
.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 2
GarbagePermission
.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<out String>, 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<String>, 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/Theme-->
<style name="Transparent" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@color/colorTransparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowActionBar">false</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowNoTitle">true</item>
</style>
为Activity设置上Style,在 Manifest
中
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.shycoder.gargabepermissionlibrary">
<application>
<activity
android:name=".PermissionActivity"
android:theme="@style/Transparent" />
</application>
</manifest>
距离成功还差一点点,虽然我们通过上面建立的Activity就已经能够进行申请权限了,但是直接开启Activity请求权限太不雅观了啊 ?? ,所以我们需要把Activity启动的过程封装一下,建立一个门面类来进行调用,假装高大上一点。
/**
* GarbagePermission 权限请求框架
* */
class GarbagePermission private constructor(private val context: Context) {
private var mPermissions: Array<String>? = null
private var mCallback: OnPermissionRequestListener? = null
/**
* 设置你要请求的权限
* */
fun permissions(permissions: Array<String>): 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到此结束,与诸君共勉。
标签:name ica etc 授权 list lis lse 实现 manage
原文地址:https://www.cnblogs.com/slyfox/p/9775493.html