Last active
September 8, 2019 12:07
-
-
Save ChekhWasTaken/79da4021fd5708a49d5e0c79e0a8e0a4 to your computer and use it in GitHub Desktop.
A class to handle permission requests and callbacks for fragments in Android.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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