admin管理员组

文章数量:1122832

I am building an Android app using Kotlin and want to use the PermissionX library to request runtime permissions from users.

I have already added the library to my project and followed the documentation, but I'm not sure how to properly implement it to request permissions such as READ_EXTERNAL_STORAGE and CAMERA.

Here is what I have tried so far:

PermissionX.init(this)
    .permissions(android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA)
    .onExplainRequestReason { scope, deniedList ->
        scope.showRequestReasonDialog(
            deniedList,
            "The app needs these permissions to work properly. Please grant them.",
            "OK",
            "Cancel"
        )
    }
    .onForwardToSettings { scope, deniedList ->
        scope.showForwardToSettingsDialog(
            deniedList,
            "You need to allow these permissions in settings manually.",
            "OK",
            "Cancel"
        )
    }
    .request { allGranted, grantedList, deniedList ->
        if (allGranted) {
            Toast.makeText(this, "All permissions are granted", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this, "These permissions are denied: $deniedList", Toast.LENGTH_SHORT).show()
        }
    }

However, when I run the app, I encounter the following issue:

The permission request dialog sometimes does not appear, and the app behaves as if the permissions were denied, even though I haven't interacted with the dialog.

I would like to know:

  1. Is this the correct way to use PermissionX for requesting permissions?
  2. How can I ensure the permissions are requested and handled properly, even if the user denies or grants them selectively? Any guidance or corrections to my code would be greatly appreciated.

I am building an Android app using Kotlin and want to use the PermissionX library to request runtime permissions from users.

I have already added the library to my project and followed the documentation, but I'm not sure how to properly implement it to request permissions such as READ_EXTERNAL_STORAGE and CAMERA.

Here is what I have tried so far:

PermissionX.init(this)
    .permissions(android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA)
    .onExplainRequestReason { scope, deniedList ->
        scope.showRequestReasonDialog(
            deniedList,
            "The app needs these permissions to work properly. Please grant them.",
            "OK",
            "Cancel"
        )
    }
    .onForwardToSettings { scope, deniedList ->
        scope.showForwardToSettingsDialog(
            deniedList,
            "You need to allow these permissions in settings manually.",
            "OK",
            "Cancel"
        )
    }
    .request { allGranted, grantedList, deniedList ->
        if (allGranted) {
            Toast.makeText(this, "All permissions are granted", Toast.LENGTH_SHORT).show()
        } else {
            Toast.makeText(this, "These permissions are denied: $deniedList", Toast.LENGTH_SHORT).show()
        }
    }

However, when I run the app, I encounter the following issue:

The permission request dialog sometimes does not appear, and the app behaves as if the permissions were denied, even though I haven't interacted with the dialog.

I would like to know:

  1. Is this the correct way to use PermissionX for requesting permissions?
  2. How can I ensure the permissions are requested and handled properly, even if the user denies or grants them selectively? Any guidance or corrections to my code would be greatly appreciated.
Share Improve this question asked Nov 21, 2024 at 12:22 Lily MontaLily Monta 214 bronze badges 1
  • The problem is probably because starting from API level 33, READ_EXTERNAL_STORAGE has no effect, causing allGranted to return false – Crebain Commented Nov 21, 2024 at 12:44
Add a comment  | 

1 Answer 1

Reset to default 0

I believe I have the right answer to the query.

This is how permissionX should be implemented in Android.

 fun requestPermissionIfNeeded(permissions: List<String>, requestCallback: RequestCallback?) {
        var allGranted = true
        for (permission in permissions) {
            if (ContextCompat.checkSelfPermission(
                    this, permission!!
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                allGranted = false
            }
        }
        if (allGranted) {
            requestCallback!!.onResult(true, permissions, ArrayList())
            return
        }

        PermissionX.init(this).permissions(permissions)
            .onExplainRequestReason(ExplainReasonCallback { scope: ExplainScope, deniedList: List<String> ->
                var message = ""
                if (permissions.size == 1) {
                    if (deniedList.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        message = this.getString(R.string.permission_explain)
                    }
                } else {
                    if (deniedList.size == 1) {
                        if (deniedList.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                            message = this.getString(R.string.permission_explain)
                        }
                    } else {
                        message = this.getString(R.string.permission_explain)
                    }
                }
                scope.showRequestReasonDialog(deniedList, message, getString(R.string.ok))
            })
            .onForwardToSettings(ForwardToSettingsCallback { scope: ForwardScope, deniedList: List<String> ->
                var message = ""
                if (permissions.size == 1) {
                    if (deniedList.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        message = this.getString(R.string.permission_explain)
                    }
                } else {
                    if (deniedList.size == 1) {
                        if (deniedList.contains(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                            message = this.getString(R.string.permission_explain)
                        }
                    } else {
                        message = this.getString(R.string.permission_explain)
                    }
                }
                scope.showForwardToSettingsDialog(
                    deniedList, message, getString(R.string.settings), getString(R.string.cancel)
                )
            }).request(RequestCallback { allGranted, grantedList, deniedList ->
                requestCallback?.onResult(
                    allGranted, grantedList, deniedList
                )
            })
    }

You can put this into practice as follows:

    val strings = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                    listOf(Manifest.permission.READ_MEDIA_IMAGES)     // For 10+
                } else {
                    listOf(Manifest.permission.READ_EXTERNAL_STORAGE)    // For below 10
                }

requestPermissionIfNeeded(strings) { allGranted, grantedList, deniedList ->
                    if (allGranted) {
                        val i = Intent(
                            Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI
                        )
                        startActivityForResult(
                            i, GALLERY_CODE
                        )
                    }
                }

本文标签: How to use PermissionX to request permissions in an Android Kotlin appStack Overflow