Reputation: 419
I need to implement a countdown timer in a Glance widget, that should be updated every second. At the bare minimum, every minute.
What would be the best approach for this using Jetpack Compose Glance widgets? First time I play with this.
I've been trying to do something like
object : CountDownTimer(startTime, 1000) {
private var coroutineScope: CoroutineScope? = null
override fun onTick(millisUntilFinished: Long) {
if (coroutineScope == null) {
coroutineScope = CoroutineScope(coroutineContext)
}
coroutineScope?.launch {
onTick?.invoke(millisUntilFinished) // calls GlanceWidget.updateAll(context)
}
}
override fun onFinish() {
coroutineScope?.cancel()
onFinish?.invoke()
}
}
Upvotes: 0
Views: 233
Reputation: 249
class CountdownGlanceWidget : GlanceAppWidget() {
override suspend fun onUpdate(context: Context, glanceId: GlanceId) {
val remainingTime = getRemainingTime()
updateAppWidget(context, glanceId, remainingTime)
}
private suspend fun updateAppWidget(context: Context, glanceId: GlanceId, remainingTime: String) {
update(context, glanceId) {
CountdownWidgetContent(remainingTime)
}
}
}
@Composable
fun CountdownWidgetContent(remainingTime: String) {
Text(
text = remainingTime,
style = TextStyle(fontSize = 24.sp, color = ColorProvider(R.color.black))
)
}
fun getRemainingTime(): String {
// Replace with your logic to compute remaining time
val targetTimeMillis = SystemClock.elapsedRealtime() + TimeUnit.MINUTES.toMillis(10)
val currentTimeMillis = SystemClock.elapsedRealtime()
val remainingMillis = targetTimeMillis - currentTimeMillis
val minutes = TimeUnit.MILLISECONDS.toMinutes(remainingMillis)
val seconds = TimeUnit.MILLISECONDS.toSeconds(remainingMillis) % 60
return String.format("%02d:%02d", minutes, seconds)
}
class CountdownUpdateWorker(
context: Context,
params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result {
val context = applicationContext
val glanceIds = GlanceAppWidgetManager(context).getGlanceIds(CountdownGlanceWidget::class.java)
for (glanceId in glanceIds) {
CountdownGlanceWidget().updateAll(context)
}
return Result.success()
}
}
fun scheduleWidgetUpdate(context: Context) {
val workRequest = PeriodicWorkRequestBuilder<CountdownUpdateWorker>(1, TimeUnit.MINUTES).build()
WorkManager.getInstance(context).enqueue(workRequest)
}
class MyApp : Application(), Configuration.Provider {
override fun onCreate() {
super.onCreate()
scheduleWidgetUpdate(this)
}
override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.INFO)
.build()
}
Upvotes: -1