📜  使用 Dexter 的 Kotlin 在 Android 中的多个运行时权限

📅  最后修改于: 2022-05-13 01:55:47.945000             🧑  作者: Mango

使用 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 消息被授予,否则将再次执行相同的过程。