运行时权限:Android(如果用户拒绝权限则调用两次)

Via*_*nko 3 android permission-denied android-permissions

我的运行时权限警报对话框有问题。这是我的代码:

button.setOnClickListener{
    requestPermissionLauncher.launch(android.Manifest.permission.CAMERA)
}

val requestPermissionLauncher =
        registerForActivityResult(
            ActivityResultContracts.RequestPermission()
        ) { isGranted: Boolean ->
            if (isGranted) {
                presenter.openCamera()
            } else {
                showMessage(getString(R.string.permission_needed))
            }
        }
Run Code Online (Sandbox Code Playgroud)

如果用户单击“相机”按钮,用户会看到此对话框(如预期): 在此输入图像描述

然后,如果用户单击“使用应用程序时”或“仅这一次”-> 一切正常,则没有问题

但是,如果用户单击“不允许”-> 他会看到一条错误消息(如预期),但如果用户第二次单击“相机”按钮 -> 权限警告对话框会再次出现。(第二次之后此对话框再也不会出现)

如果用户第一次拒绝权限,为什么此警报对话框会出现两次?它应该只出现一次,第二次单击后用户可能会立即看到错误消息

Sas*_*vic 16

简而言之:对话框出现两次,因为如果用户第一次单击“拒绝”,下次系统建议在请求权限之前显示一个理由对话框,并且 shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA) 返回 true。您可以检查这是否属实,并且不再显示您的权限对话框。如果您不手动检查此布尔值,如果为真,系统将自动再次显示权限对话框。请记住,如果用户在权限对话框之外单击,则其处理方式与用户单击“拒绝”相同。

当用户第二次拒绝权限时,您将无法再次显示权限对话框。用户允许权限的唯一方法是转到系统设置中的应用程序信息并手动允许请求的权限(不建议这样做)。

来自文档

请求权限的工作流程 =>

...

步骤4、检查用户是否已授予运行时权限。如果没有,请继续执行下一步。

步骤 5. 检查您的应用程序是否应向用户显示理由,解释为什么您的应用程序需要用户授予权限。

...

来自developer.android.com 的权限图

例子:

if (checkSelfPermission(android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
        // Application can use camera
    } else if (shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA)) {
        /*
        This is the second time when system is about to show permission dialog.

        You can show your alert dialog here if you want to explain to user what are benefits if allow your requested permission (CAMERA in this case). Also, you can show
        permission dialog on "OK" click, and do nothing on "No, thank you".

        KEEP IN MIND THAT WITH THIS APPROACH YOU WILL SHOW ALERT DIALOG TO THE USER EVERY TIME YOU CHECK IF PERMISSION IS NOT GRANTED BUT
        shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA) RETURNS TRUE. THIS CAN BE ANNOYING TO THE USER AND YOU SHOULD
        AVOID THIS PART OF CODE. THIS IS JUST FOR TESTING PURPOSES.

        *** YOU SHOULD SHOW THIS ALERT DIALOG WHEN REGISTERING YOUR ACTIVITY FOR PERMISSION RESULT, IF PERMISSION IS NOT GRANTED!!!***
         */
        AlertDialog.Builder(this@YourActivity)
            .setMessage(
                "Your message"
            )
            .setPositiveButton(
                "OK"
            ) { _, _ ->
                // Show permission dialog
                requestPermissionLauncher.launch(android.Manifest.permission.CAMERA)
            }
            .setNegativeButton(
                "No, thank you"
            ) { _, _ -> }
            .create().show()

        /*
        IF YOU DON'T WANT TO SHOW ALERT_DIALOG FROM ABOVE, HERE YOU CAN SIMPLY SHOW PERMISSION DIALOG
        
        requestPermissionLauncher.launch(android.Manifest.permission.CAMERA)
         */
    } else {
        /*
        This part of code is active first time when you are going to request the permission, and last time (after second "Deny" by a user,
        or simply, when permission is not granted and shouldShowRequestPermissionRationale(android.Manifest.permission.CAMERA) returns false
         */
        requestPermissionLauncher.launch(android.Manifest.permission.CAMERA)
    }
Run Code Online (Sandbox Code Playgroud)

正如我在开头提到的,您可以将用户导航到可以允许权限的应用程序设置,但根据 Google 的文档,您应该避免这样做。文档中的消息:“......尊重用户的决定。不要链接到系统设置来说服用户改变他们的决定。”

即使您想导航用户,也可以使用下一个代码块来实现:

val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
val uri = Uri.fromParts("package", packageName, null)
intent.data = uri
startActivity(intent)
Run Code Online (Sandbox Code Playgroud)