Skip to content

Instantly share code, notes, and snippets.

@ChekhWasTaken
Last active September 8, 2019 12:07
Show Gist options
  • Save ChekhWasTaken/79da4021fd5708a49d5e0c79e0a8e0a4 to your computer and use it in GitHub Desktop.
Save ChekhWasTaken/79da4021fd5708a49d5e0c79e0a8e0a4 to your computer and use it in GitHub Desktop.
A class to handle permission requests and callbacks for fragments in Android.
import android.content.Context
import android.content.pm.PackageManager
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
typealias GrantedCallback = () -> Unit
typealias DeniedCallback = () -> Unit
data class PermissionRequest(
val requestCode: Int,
val permission: String,
val grantedCallback: GrantedCallback,
val deniedCallback: DeniedCallback? = null
)
interface PermissionDelegate {
fun performRequest(context: Context, fragment: Fragment, permissionRequest: PermissionRequest)
fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
)
}
class PermissionDelegateImpl(private val permissionRequests: List<PermissionRequest>) :
PermissionDelegate {
override fun performRequest(
context: Context,
fragment: Fragment,
permissionRequest: PermissionRequest
) {
require(permissionRequest in permissionRequests) { "$permissionRequest not found in submitted requests" }
when (ContextCompat.checkSelfPermission(context, permissionRequest.permission)) {
PackageManager.PERMISSION_GRANTED -> permissionRequest.grantedCallback()
PackageManager.PERMISSION_DENIED -> fragment.requestPermissions(
arrayOf(
permissionRequest.permission
), permissionRequest.requestCode
)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
val permissionsResult = getPermissionResultMap(permissions, grantResults)
permissionRequests.firstOrNull { it.requestCode == requestCode }?.let { permissionRequest ->
permissionsResult[permissionRequest.permission]?.also {
if (it) {
permissionRequest.grantedCallback()
} else {
permissionRequest.deniedCallback?.invoke()
}
}
}
}
private fun getPermissionResultMap(
permissions: Array<out String>,
grantResults: IntArray
): Map<String, Boolean> {
val isGranted = { grantResult: Int -> grantResult == PackageManager.PERMISSION_GRANTED }
val map = mutableMapOf<String, Boolean>()
permissions.forEachIndexed { index: Int, value: String ->
map[value] = isGranted(grantResults[index])
}
return map
}
}
/* usage */
class UsageExample : Fragment() {
private val permissionRequst =
PermissionRequest(1, Manifest.permission.WRITE_EXTERNAL_STORAGE, {
println("permission granted")
})
private val anotherPermissionRequeast =
PermissionRequest(2, Manifest.permission.WRITE_CONTACTS, {
println("also permission granted")
})
private val permissionDelegate =
PermissionDelegateImpl(listOf(permissionRequst, anotherPermissionRequeast))
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.button_color_blue).setOnClickListener {
permissionDelegate.performRequest(requireContext(), this, permissionRequst)
}
view.findViewById<Button>(R.id.button_color_green).setOnClickListener {
permissionDelegate.performRequest(requireContext(), this, anotherPermissionRequeast)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) = permissionDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment