Skip to content

Instantly share code, notes, and snippets.

@whileloop99
Last active January 10, 2022 02:23
Show Gist options
  • Save whileloop99/d8bc8b2e62d53226b88703798ea98c74 to your computer and use it in GitHub Desktop.
Save whileloop99/d8bc8b2e62d53226b88703798ea98c74 to your computer and use it in GitHub Desktop.
Kotlin: Better Way to Request Runtime Permissions
package your.business
import android.content.pm.PackageManager
import android.os.Bundle
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.app.ActivityCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
/**
* Request permissions
*
* Usage:
* val allGranted = requestAppPermissions(context, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO) { notGrantedPermissions ->
* // Some error messages?
* }
*
* if (allGranted) {
* startCamera()
* }
*/
suspend fun requestPermissions(
activity: FragmentActivity,
vararg permissions: String,
nonShowRequestPermissionRationaleHandler: ((List<String>) -> Unit)? = null
) = suspendCoroutine<Boolean> { emitter ->
val nonShowRequestPermissions = mutableListOf<String>()
val nonGrantedPermissions = mutableListOf<String>()
var allGranted = true
permissions.forEach { perm ->
val granted = ActivityCompat.checkSelfPermission(activity, perm) == PackageManager.PERMISSION_GRANTED
if (!granted) {
allGranted = false
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, perm)) {
nonShowRequestPermissions.add(perm)
} else {
nonGrantedPermissions.add(perm)
}
}
}
if (allGranted) {
emitter.resume(allGranted)
return@suspendCoroutine
}
class RequestPermissionFragment : Fragment() {
lateinit var activityResultLauncher: ActivityResultLauncher<Array<String>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
activityResultLauncher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { resultMap ->
allGranted = resultMap.values.all { true }
if (nonShowRequestPermissions.isNotEmpty()) {
allGranted = false
nonShowRequestPermissionRationaleHandler?.invoke(nonShowRequestPermissions)
}
emitter.resume(allGranted)
activity.supportFragmentManager.beginTransaction().remove(this).commit()
}
activityResultLauncher.launch(nonGrantedPermissions.toTypedArray())
}
}
activity.supportFragmentManager.beginTransaction().add(0, RequestPermissionFragment()).commit()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment