I wonder if anyone sees a better way to request pe...
# compose-android
k
I wonder if anyone sees a better way to request permission to read device contacts, and then re-sync each time the app is resumed? I want to make sure I don’t recompose anything too often. Normally I would put this sort of thing in a
LaunchedEffect
so that it would run only once, but then I can’t call composables(such as
rememberLauncherForActivityResult
) inside a
LaunchedEffect
. Code in thread. Maybe add a 👍 if it looks good, or 👎 if perhaps you see something less than ideal?
Copy code
@Composable
fun ViewContactsScreen(...) {

    // Call things like viewModel.getAllContacts to read from Room
    Column() {
        // display contacts from Room
    }

    // Get permission to read contacts and then ask viewModel 
    // to ask Repository to read contacts and save to Room
    val permissionGranted by viewModel.permissionGranted.collectAsStateWithLifecycle()

    var permissionRequested by remember { mutableStateOf(false) }

    if (!permissionGranted && !permissionRequested) {
        RequestContactsPermission {
            permissionRequested = true
            viewModel.permissionGranted.tryEmit(it)
        }
    }

    LifecycleResumeEffect(permissionGranted) {
        if (permissionGranted) {
            viewModel.syncContacts()
        }
        onPauseOrDispose {  }
    }
}

@Composable
fun RequestContactsPermission(
    onResult: (isGranted: Boolean) -> Unit,
) {
    val context = LocalContext.current
    var hasGrantedPermission by remember {
        mutableStateOf(
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                true
            } else {
                context.checkSelfPermission(READ_CONTACTS) == PERMISSION_GRANTED
            }
        )
    }
    if (hasGrantedPermission) {
        onResult(true)
        return
    }

    val readContactsPermissionLauncher = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.RequestPermission()
    ) { isGranted ->
        hasGrantedPermission = isGranted
        onResult(isGranted)
    }

    LaunchedEffect(Unit) {
        readContactsPermissionLauncher.launch(Manifest.permission.READ_CONTACTS)
    }
}