Composable Function
Android
@Composable
public fun AmbientModeManager.AmbientTickEffect(block: () -> Unit)
A convenience extension that performs recurrent, battery-efficient UI updates when the device is in AmbientMode.Ambient.
This extension handles the boilerplate for ambient tick synchronization: it automatically launches and manages a LaunchedEffect that repeatedly suspends using AmbientModeManager.withAmbientTick to align state updates with the system's infrequent ambient tick schedule.
The internal loop automatically terminates when the device returns to AmbientMode.Interactive.
Efficiency Note: The block lambda should only update the minimal androidx.compose.runtime.State required to prevent excessive recomposition and maximize battery life.
Example of using AmbientTickEffect:
Parameters
| block | The state update logic to execute once per ambient tick. |
Code Examples
AmbientModeWithAmbientTickSample
@Composable
fun AmbientModeWithAmbientTickSample() {
// **Best Practice Note:** In a production application, the AmbientModeManager should be
// instantiated and provided at the highest level of the Compose hierarchy (typically in
// the host Activity's setContent block) using a CompositionLocalProvider. This ensures
// proper lifecycle management and broad accessibility.
// For this self-contained demo, AmbientModeManager is created and provided locally:
val activityAmbientModeManager = rememberAmbientModeManager()
CompositionLocalProvider(LocalAmbientModeManager provides activityAmbientModeManager) {
var counter by remember { mutableIntStateOf(0) }
val ambientModeManager = LocalAmbientModeManager.current
ambientModeManager?.AmbientTickEffect {
// While device is in ambient mode, update counter in onAmbientTick approx. every minute
counter++
}
val ambientMode = ambientModeManager?.currentAmbientMode
if (ambientMode is AmbientMode.Interactive) {
// While device is not in ambient mode, update counter approx. every second
LaunchedEffect(Unit) {
while (true) {
delay(1000L)
counter++
}
}
}
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.fillMaxSize(),
) {
val ambientModeName =
when (ambientMode) {
is AmbientMode.Interactive -> "Interactive"
is AmbientMode.Ambient -> "Ambient"
else -> "Unknown"
}
val updateInterval = if (ambientMode is AmbientMode.Ambient) "minute" else "second"
val color = if (ambientMode is AmbientMode.Ambient) Color.Gray else Color.Yellow
Text(text = "$ambientModeName Mode", color = color)
Text(text = "Updates every $updateInterval")
Text(text = "$counter")
}
}
}