前言
前面我們有講到權(quán)限申請相關(guān)文章晋南,大家感興趣的話可以參考以下文章:
PermissionsDispatcher動態(tài)權(quán)限申請
PermissionsDispatcher動態(tài)權(quán)限申請kotlin版
RxPermission申請權(quán)限
今天我們來講講ActivityResultLauncher
實(shí)現(xiàn)的動態(tài)權(quán)限申請恒界。具體使用我已經(jīng)將其封裝成工具類
PermissionHelper
,下面就來具體講下它的使用吧踩蔚。
今天涉及內(nèi)容:
1.添加依賴
2.PermissionHelper
中方法簡單介紹
3.PermissionHelper
在MainActivity
中的使用
4.運(yùn)行效果
5.PermissionHelper
相關(guān)源碼
一.添加依賴
由于androidstudio
已經(jīng)Compose
化,相關(guān)Activity
已經(jīng)默認(rèn)引用"androidx.activity:activity-compose:1.7.0"
禾嫉,從而導(dǎo)致ActivityResultLauncher
在使用上無法識別灾杰,所以我們需要在app_module
的build.gradle
中引入以下依賴:
dependencies {
implementation("androidx.appcompat:appcompat:1.7.0")
//其他代碼省略
//......
}
這樣我們在使用ActivityResultLauncher
及相關(guān)方法的時(shí)候,才不會報(bào)錯(cuò)熙参。
二. PermissionHelper 中方法簡單介紹
作為權(quán)限申請的工具類PermissionHelper
中具有以下公開方法:
/**
* 監(jiān)聽權(quán)限返回處理
*
* @param listener 權(quán)限返回監(jiān)聽類
* @return 返回 ActivityResultLauncher<Array<String>> 對象
*/
fun getRequestPermissionLauncher(listener: IPermissionListener): ActivityResultLauncher<Array<String>>
/**
* 發(fā)起權(quán)限申請
*
* @param resultLauncher ActivityResultLauncher<Array<String>>對象
*/
fun requestPermissions(resultLauncher: ActivityResultLauncher<Array<String>>)
/**
* 檢測是否permisson已經(jīng)授權(quán)
*
* @param permission eg: Manifest.permission.READ_EXTERNAL_STORAGE
* @return boolean true:已授權(quán) false:未授權(quán)
*/
fun checkSelfPermission(permission: String): Boolean
/**
* 檢測是否需要給未授權(quán)權(quán)限給出拒絕理由
*
* @param permission eg: Manifest.permission.READ_EXTERNAL_STORAGE
* @return boolean true:需要給出拒絕理由 false:不需要給出拒絕理由
*/
fun checkShouldShowPermissionDescription(permission: String): Boolean
三. PermissionHelper 在 MainActivity 中的使用
代碼示例中使用的是ViewBinding
初始化控件艳吠,大家如果對ViewBinding
使用不甚了解的話,可以參考以下文章:
ViewBinding(1) — 在Activity中使用
ViewBinding(2) — Activity中ViewBinding和include標(biāo)簽使用
ViewBinding(3) — ViewBinding在fragment中使用
ViewBinding(4) — ViewBinding在Adapter中使用
MainActivity
中申請權(quán)限是以讀寫和定位權(quán)限為例孽椰,所以需要在AndroidManifest.xml
中添加以下權(quán)限:
<!-- 讀寫權(quán)限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 定位權(quán)限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
接下來讓我們看看PermissionHelper
在MainActivity
中的使用:
package com.example.kdemo.ui
import android.Manifest
import android.os.Bundle
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.appcompat.app.AppCompatActivity
import com.example.kdemo.R
import com.example.kdemo.bean.StudentBean
import com.example.kdemo.databinding.ActivityMainBinding
import com.example.kdemo.permission.PermissionHelper
import com.example.kdemo.util.LogUtil
class MainActivity : AppCompatActivity() {
private lateinit var mBinding:ActivityMainBinding
private lateinit var mPermissionHelper:PermissionHelper
private lateinit var mActivityResultLauncher:ActivityResultLauncher<Array<String>>
private var mPermissions = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_FINE_LOCATION
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(mBinding.root)
initData()
setListener()
}
protected val initData = {
mBinding.mTvName.text="我是中國人"
var studentBean=StudentBean("小華",13)
LogUtil.i("studentBean=${studentBean}")
mPermissionHelper = PermissionHelper(this@MainActivity,mPermissions)
//監(jiān)聽申請結(jié)果
mActivityResultLauncher = mPermissionHelper.getRequestPermissionLauncher(object :
PermissionHelper.IPermissionListener {
override fun requestSuccess() {
LogUtil.i("permission request success")
}
override fun shouldShowPermissionDescription(descriptionList: MutableList<String>) {
LogUtil.i("permission request should show description dialog: ")
descriptionList.forEach {
LogUtil.i("description permission: $it")
}
}
override fun requestFail(requestFailList: MutableList<String>) {
LogUtil.i("permission request fail")
requestFailList.forEach {
LogUtil.i("fail permission: $it")
}
}
})
}
protected val setListener = {
mBinding.mTvName.setOnClickListener {
when(it.id){
// R.id.mTvName ->toast("大家好")
R.id.mTvName ->{
LogUtil.i("start request permission")
//申請權(quán)限
mPermissionHelper.requestPermissions(mActivityResultLauncher)
LogUtil.i("request permission over")
}
}
}
}
protected val toast: (String) -> Unit = {
Toast.makeText(this@MainActivity, it, Toast.LENGTH_SHORT).show()
}
}
從以上代碼可以看到昭娩,MainActivity
在執(zhí)行初始化操作時(shí),我們初始化了PermissionHelper
對象并傳入了權(quán)限數(shù)組黍匾。初始化ActivityResultLauncher
對象的時(shí)候監(jiān)聽權(quán)限申請的結(jié)果回調(diào)栏渺。然后在需要申請權(quán)限的地方調(diào)用:
//申請權(quán)限
mPermissionHelper.requestPermissions(mActivityResultLauncher)
需要注意的是,在權(quán)限申請回調(diào)中有三個(gè)方法:
//申請權(quán)限成功
fun requestSuccess()
//拒絕授權(quán)需要提供理由
fun shouldShowPermissionDescription(descriptionList: MutableList<String>)
//申請權(quán)限失敗的權(quán)限列表
fun requestFail(requestFailList: MutableList<String>)
fun requestSuccess()
:權(quán)限申請成功的處理锐涯,在此處你可以做你app
內(nèi)部需要處理的邏輯磕诊。
fun shouldShowPermissionDescription(descriptionList: MutableList<String>)
:權(quán)限被用戶拒絕,然后你需要給出申請這些權(quán)限的理由,用于引導(dǎo)用戶給予權(quán)限霎终,此方法返回的是被用戶拒絕的權(quán)限列表滞磺,你可以再此彈出dialog
并羅列被拒絕的權(quán)限,并給出各權(quán)限申請的理由以引導(dǎo)用戶繼續(xù)授權(quán)
fun requestFail(requestFailList: MutableList<String>)
申請用戶授權(quán)失敗莱褒,返回授權(quán)失敗的權(quán)限列表击困,在此方法內(nèi),你可以羅列哪些權(quán)限申請被拒絕广凸,并以彈出dialog
的方式告知用戶
四.運(yùn)行效果
此次運(yùn)行后阅茶,界面先彈出是否授權(quán)位置,我選擇拒絕谅海,接著彈出是否授權(quán)拍照和相冊權(quán)限的dialog
目派,我選擇允許,然后運(yùn)行的日志如下:
start request permission
request permission over
permission request fail
fail permission: android.permission.ACCESS_FINE_LOCATION
可以看到fun requestFail(requestFailList: MutableList<String>)
執(zhí)行并返回位置授權(quán)失敗胁赢。
五.PermissionHelper 相關(guān)源碼
下面給出PermissionHelper
類源碼: