使用 Dexter 的 Kotlin 在 Android 中的多个运行时权限
从MarshMallow android 引入运行时权限,我们可以在使用应用程序时授予权限,而不是在安装应用程序时授予。一般来说,如果您想使用相机或从您的应用程序中拨打电话,您将征求用户的许可。提供了一些预定义的功能来询问并了解用户是否已授予权限。
假设我们需要用户权限,我们将使用以下函数请求权限
Kotlin
requestPermissions(arrayOf(Manifest.permission.READ_PHONE_STATE),
Manifest.permission.WRITE_EXTERNAL_STORAGE
ABConstants.REQUEST_CODE_FOR_PERMISSIONS)
Kotlin
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
Kotlin
class MainActivity : AppCompatActivity() {
lateinit var dexter : DexterBuilder
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
checkThePermissions()
}
}
Kotlin
private fun getPermission() {
dexter = Dexter.withContext(this)
.withPermissions(
android.Manifest.permission.CAMERA,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_PHONE_STATE
).withListener(object : MultiplePermissionsListener {
override fun onPermissionsChecked(report: MultiplePermissionsReport) {
report.let {
if (report.areAllPermissionsGranted()) {
Toast.makeText(this@MainActivity, "Permissions Granted", Toast.LENGTH_SHORT).show()
} else {
AlertDialog.Builder(this@MainActivity, R.style.Theme_AppCompat_Dialog).apply {
setMessage("please allow the required permissions")
.setCancelable(false)
.setPositiveButton("Settings") { _, _ ->
val reqIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.apply {
val uri = Uri.fromParts("package", packageName, null)
data = uri
}
resultLauncher.launch(reqIntent)
}
// setNegativeButton(R.string.cancel) { dialog, _ -> dialog.cancel() }
val alert = this.create()
alert.show()
}
}
}
}
override fun onPermissionRationaleShouldBeShown(permissions: List?, token: PermissionToken?) {
token?.continuePermissionRequest()
}
}).withErrorListener{
Toast.makeText(this, it.name, Toast.LENGTH_SHORT).show()
}
dexter.check()
}
Kotlin
resultLauncher.launch(reqIntent)
Kotlin
private var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result -> dexter.check()
}
在这里,我们向用户询问 arrayOf 权限,一旦用户被允许/拒绝,我们将得到如下回调的结果。
科特林
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
在此回调中,我们可以检查用户是否已授予权限。如果没有给出,我们必须再次通过将用户带到设置页面来询问他。用户可能只授予一个权限而没有授予,那么这很难处理,我们需要为此编写大量的逻辑代码。为了简化这类问题,我们使用了 Dexter 库。只需在 Gradle 中添加这个库,如下所示。
implementation 'com.karumi:dexter:6.2.2'
它是如何工作的?
1.在活动中添加一个全局变量和checkThePermissions函数。
科特林
class MainActivity : AppCompatActivity() {
lateinit var dexter : DexterBuilder
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
checkThePermissions()
}
}
2.让我们在这里实现如下函数
科特林
private fun getPermission() {
dexter = Dexter.withContext(this)
.withPermissions(
android.Manifest.permission.CAMERA,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
android.Manifest.permission.READ_PHONE_STATE
).withListener(object : MultiplePermissionsListener {
override fun onPermissionsChecked(report: MultiplePermissionsReport) {
report.let {
if (report.areAllPermissionsGranted()) {
Toast.makeText(this@MainActivity, "Permissions Granted", Toast.LENGTH_SHORT).show()
} else {
AlertDialog.Builder(this@MainActivity, R.style.Theme_AppCompat_Dialog).apply {
setMessage("please allow the required permissions")
.setCancelable(false)
.setPositiveButton("Settings") { _, _ ->
val reqIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
.apply {
val uri = Uri.fromParts("package", packageName, null)
data = uri
}
resultLauncher.launch(reqIntent)
}
// setNegativeButton(R.string.cancel) { dialog, _ -> dialog.cancel() }
val alert = this.create()
alert.show()
}
}
}
}
override fun onPermissionRationaleShouldBeShown(permissions: List?, token: PermissionToken?) {
token?.continuePermissionRequest()
}
}).withErrorListener{
Toast.makeText(this, it.name, Toast.LENGTH_SHORT).show()
}
dexter.check()
}
3.让我们理解代码
在第一个参数中,我们传递活动上下文,在第二个参数中,我们传递一个权限列表,就像 arrayOf 一样。在第三个参数中,我们必须实现具有 onPermissionsChecked函数的 MultiplePermissionsListener ,在此函数中我们获取有关已授予或未授予权限的报告。如果授予了所有权限,那么我们将显示 toast 消息已授予,否则我们需要显示具有设置按钮的对话框。当用户点击设置按钮时,我们将花时间进入应用设置页面,用户可以在其中手动允许/拒绝权限。当用户从设置页面返回时,我们应该知道他是否同意。为此,我们必须使用 startActivityForResult ,在这里我们添加如下代码
科特林
resultLauncher.launch(reqIntent)
我们得到如下的 OnActivityResult 回调
科特林
private var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
result -> dexter.check()
}
dexter.check()函数再次检查权限,如果所有权限都被授予,那么我们将显示 toast 消息被授予,否则将再次执行相同的过程。