Kevin Worth
09/25/2023, 7:46 PMLaunchedEffect
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?Kevin Worth
09/25/2023, 7:46 PM@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)
}
}