Lilly
05/27/2020, 4:44 PMAdam Powell
05/27/2020, 11:50 PMLilly
05/28/2020, 4:06 PMAdam Powell
05/28/2020, 7:08 PMcodeslubber
05/29/2020, 11:55 PMAdrian Devezin
06/18/2020, 12:44 AMArchie
10/15/2020, 2:14 PMclass PermissionHandler(
private val activity: AppCompatActivity
) {
fun requestPermission(
permission: String,
onResultReceived: (PermissionResult) -> Unit,
) {
val requestPermissionLauncher = activity.registerForActivityResult(
ActivityResultContracts.RequestPermission(),
) { granted ->
onResultReceived(
if (granted)
PermissionResult.Granted
else
PermissionResult.Denied
)
}
when {
ContextCompat.checkSelfPermission(
activity,
permission
) == PackageManager.PERMISSION_GRANTED -> {
onResultReceived(PermissionResult.Granted)
}
ActivityCompat.shouldShowRequestPermissionRationale(
activity,
permission
) -> {
onResultReceived(PermissionResult.ShowRationale)
}
else -> requestPermissionLauncher.launch(permission)
}
}
}
@Composable
fun requestPermission(
permission: String,
): State<PermissionResult> {
val permissionHandler = AmbientPermissionHandler.current
val permissionResult = remember(permission) {
mutableStateOf<PermissionResult>(PermissionResult.Requesting)
}
remember(permission) {
permissionHandler.requestPermission(permission) {
permissionResult.value = it
}
}
return permissionResult
}
sealed class PermissionResult {
object Requesting : PermissionResult()
object ShowRationale : PermissionResult()
object Denied : PermissionResult()
object Granted : PermissionResult()
}
val AmbientPermissionHandler: ProvidableAmbient<PermissionHandler> =
staticAmbientOf { throw IllegalStateException("permission handler is not initialized") }
and then provide PermissionHandler
as an ambient like so:
Providers(AmbientPermissionHandler provides permissionHandler) {
....
}
so then I could use it like so:
val permissionResult by requestPermission(permission = Manifest.permission.CAMERA)
when (missionResult) {
PermissionResult.Requesting -> Text("Requesting")
PermissionResult.ShowRationale -> Text("Show Rationale")
PermissionResult.Denied -> Text("Denied")
PermissionResult.Granted -> Text("Granted")
}
The problem is when I get to the Composable
where the code above is located, I get the error:
LifecycleOwner ... is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
at androidx.activity.result.ActivityResultRegistry.register
...
I not really sure if I made everything correctly but based on the error logs, it seems that it isn't possible to create registerForActivityResult(...)
inside @Composable
as at the point the app is already at LifecycleState.RESUMED
?
Is there any advise which you could give?