class PermissionDialog : DialogFragment() {
companion object {
fun requestPermissions(fragment: Fragment, permissions: List<String>, payload: Any? = null) {
val allPermissionAreGranted = permissions.all { PermissionUtil.isGranted(fragment.requireContext(), it) }
if (allPermissionAreGranted) {
val status =
permissions.map { it to PermissionStatus.GRANTED }.toMap()
(fragment as Callback).onPermissionsResult(status, payload)
} else {
show(fragment.childFragmentManager, permissions, payload)
}
}
private fun show(fragmentManager: FragmentManager, permissions: List<String>, payload: Any?) {
if (fragmentManager.findFragmentByTag(TAG) == null) {
PermissionDialog()
.withArgs(
PERMISSIONS_EXTRA to permissions.toTypedArray(),
PAYLOAD_EXTRA to payload
)
.show(fragmentManager, TAG)
}
}
}
private val permissions by args<Array<String>>(PERMISSIONS_EXTRA, emptyArray())
private val payload by args<Any?>(PAYLOAD_EXTRA)
private var isRationaleCache = HashMap<String, Boolean>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
isCancelable = false
for (permission in permissions) {
isRationaleCache[permission] = shouldShowRequestPermissionRationale(permission)
}
requestPermissions(permissions, PERMISSION_REQUEST_CODE)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_CODE && permissions.isNotEmpty()) {
val result = mutableMapOf<String, PermissionStatus>()
permissions.forEachIndexed { index, permission ->
result[permission] = when {
grantResults[index] == PackageManager.PERMISSION_GRANTED -> PermissionStatus.GRANTED
shouldShowRequestPermissionRationale(permission) -> PermissionStatus.DENIED
isRationaleCache[permission] == true -> PermissionStatus.DENIED
else -> PermissionStatus.PERMANENTLY_DENIED
}
}
(parentFragment as Callback).onPermissionsResult(result, payload)
dismissAllowingStateLoss()
}
}
interface Callback {
fun onPermissionsResult(status: Map<String, PermissionStatus>, payload: Any?)
}
}