Skip to content

Instantly share code, notes, and snippets.

@mmoczkowski
Last active April 16, 2022 08:34
Show Gist options
  • Save mmoczkowski/ff349309bc8d0351c9de2c099b0cdd8e to your computer and use it in GitHub Desktop.
Save mmoczkowski/ff349309bc8d0351c9de2c099b0cdd8e to your computer and use it in GitHub Desktop.
Async permissions with Kotlin coroutines
package io.stanwood.bitrise

import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import kotlinx.coroutines.experimental.CancellableContinuation
import kotlinx.coroutines.experimental.suspendCancellableCoroutine
import java.util.concurrent.atomic.AtomicInteger

@SuppressLint("Registered")
open class PermissionActivity: AppCompatActivity() {
    private val permissionRequestCounter = AtomicInteger(0)
    private val uid: Int
        get() = permissionRequestCounter.getAndIncrement()
    private val permissionListeners: MutableMap<Int, CancellableContinuation<Boolean>> = mutableMapOf()

    private fun requestPermissions(vararg permissions: String, continuation: CancellableContinuation<Boolean>) {
        val isRequestRequired =
                permissions
                        .map { ContextCompat.checkSelfPermission(this, it) }
                        .any { result -> result == PackageManager.PERMISSION_DENIED }

        if(isRequestRequired) {
            ActivityCompat.requestPermissions(this, permissions, uid)
        } else {
            continuation.resume(true)
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        val isGranted = grantResults.all { result -> result == PackageManager.PERMISSION_GRANTED }
        permissionListeners
                .remove(requestCode)
                ?.resume(isGranted)
    }

    suspend fun requestPermissions(vararg permissions: String): Boolean =
        suspendCancellableCoroutine { continuation -> requestPermissions(*permissions, continuation = continuation) }
}
@haashem
Copy link

haashem commented Apr 16, 2022

The above gist is not working. because permissionListeners are empty all the time. you need to add continuation to them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment