androidkotlinandroid-jetpack-composeandroid-jetpackruntime-permissions

Type inference failed in kotlin jetpack compose


I am following this issue from accompanist permission. The person is using single permission request from the issue. I am trying to convert to work for multiple permission.

package com.vivek.permission

import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import androidx.core.app.ActivityCompat
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.vivek.permission.ui.theme.PermissionTheme

class MainActivity : ComponentActivity() {

    private val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        listOf(
            Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.BLUETOOTH_SCAN,
            Manifest.permission.BLUETOOTH_CONNECT,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
        )
    } else {
        listOf(
            Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_FINE_LOCATION,
        )
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            PermissionTheme {
                val requestState = rememberRequestPermissionsState(permissions = permissions)
                RequestPermissions(
                    requestState = requestState,
                    granted = {
                        // do stuff here
                    },
                    showRational = {
                        // show Rational here
                    },
                    permanentlyDenied = {

                    }
                )
            }
        }
    }

    class RequestPermissionState(initRequest: Boolean, val permissions: List<String>) {
        var request by mutableStateOf(initRequest)
    }

    @Composable
    fun rememberRequestPermissionsState(
        initRequest: Boolean = false,
        permissions: List<String>
    ): RequestPermissionState {
        return remember {
            RequestPermissionState(initRequest, permissions)
        }
    }

    @OptIn(ExperimentalPermissionsApi::class)
    @Composable
    fun RequestPermissions(
        requestState: RequestPermissionState,
        granted: () -> Unit,
        showRational: () -> Unit,
        permanentlyDenied: () -> Unit
    ) {
        val context = LocalContext.current
        val permissionState =
            rememberMultiplePermissionsState(permissions = requestState.permissions) { onPermissionsResult ->
                val permissionPermanentlyDenied = onPermissionsResult.filter {
                    !ActivityCompat.shouldShowRequestPermissionRationale(
                        context.findActivity(),
                        it.key
                    ) && !it.value
                }.isNotEmpty()
                if (permissionPermanentlyDenied) {
                    permanentlyDenied()
                } else if (!onPermissionsResult.containsKey(false)) {
                    showRational()
                }
            }

        if (requestState.request) {
            requestState.request = false

            if (permissionState.allPermissionsGranted) {
                granted()
            } else {
                LaunchedEffect(key1 = Unit) {
                    permissionState.launchMultiplePermissionRequest()
                }
            }

        }
    }

    internal fun Context.findActivity(): Activity {
        var context = this
        while (context is ContextWrapper) {
            if (context is Activity) return context
            context = context.baseContext
        }
        throw IllegalStateException("Permissions should be called in the context of an Activity")
    }
}

When I am unable to fix this problem for showRational() check condition. It giving me error can someone guide me on this

Type inference failed. The value of the type parameter K should be mentioned in input types (argument types, receiver type or expected type). Try to specify it explicitly.

Is this right way of check permission for rational ?

enter image description here


Solution

  • onPermissionsResult is a Map<String, Boolean>.

    You are using the method: Map<out K, *>.containsKey(key: K): Boolean.

    The key in your case is a String not a boolean.