Is there some way to override a function of superclass either from extension functions or from interfaces in kotlin?

273 Views Asked by At

In android to do some tasks we require the user to grant related permissions. Complete process of checking and requesting permission involves 3 steps: checking permission, requesting permission and checking result. If the permission is denied, then don't need to run that task. So to simplify this, I wrote the following interface and extension function in ActivityExtensions.kt

private val permissionTaskSource = HashMap<Int, TaskCompletionSource<Boolean>>()

interface PermissionHandler {
    @RequiresApi(Build.VERSION_CODES.M)
    fun Activity.permissionRequest(requestCode: Int, vararg permissions: String): Task<Boolean> {
        requestPermissions(permissions, requestCode)
        val tcs = TaskCompletionSource<Boolean>()
        permissionTaskSource[requestCode] = tcs
        return tcs.task
    }

    fun permissionResult(requestCode: Int, grantResults: IntArray) {
        permissionTaskSource[requestCode]!!.setResult(grantResults.all { it == PERMISSION_GRANTED })
        permissionTaskSource.remove(requestCode)
    }
}

suspend fun <T> T.requiresPermission(vararg permissions: String): Unit? where T : Activity, T : PermissionHandler {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
        return Unit   // If version lower than M then no need of runtime permissions.
    if (permissions.all { ContextCompat.checkSelfPermission(this, it) == PERMISSION_GRANTED })
        return Unit   // If already all permissions granted, then no need to ask again.

    val granted = permissionRequest(System.currentTimeMillis().toInt(), *permissions).await()
    if (granted)
        return Unit   // Permission granted now
    return null   // Permission denied now
}

Whenever required some permissions to do a task in an activity or fragment, I can use this line:

private suspend fun someTask() {
    requiresPermission(/* list of required permissions */) ?: run{ /*permission denied. handle properly*/ return }
    // Inside fragment this has to be called with requiresActivity() receiver.
    ...
}

This whole thing is working fine.. but in every activity/fragment I have to write these 4 lines of code.

override fun onRequestPermissionsResult(
    requestCode: Int, permissions: Array<out String>, grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    permissionResult(requestCode, grantResults)
}

Is there some way I can move these codes also to ActivityExtensions.kt file to make it much neater and avoid repetitive code?

0

There are 0 best solutions below