I want to update my Glance App Widget state inside CoroutineWorker:
class MyWorker(appContext: Context, workerParams: WorkerParameters) :
CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
val glanceId = GlanceAppWidgetManager(applicationContext).getGlanceIds(MyWidget::class.java).first()
updateAppWidgetState(
context = applicationContext,
glanceId = glanceId,
) { preferences ->
preferences.toMutablePreferences().apply{
this[stringPreferencesKey(TASK_ID)] = id.toString()
}
}
MyWidget().updateAll(applicationContext)
return Result.success()
}
}
This worker ends with success, but widget state is not updated.
class MyWidget : GlanceAppWidget() {
override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition
@Composable
override fun Content() {
val context = LocalContext.current
val preferences = currentState<Preferences>()
val taskId = preferences[stringPreferencesKey(TASK_ID)]
if (taskId.isNullOrEmpty()) {
val myWorker = OneTimeWorkRequestBuilder<MyWorker>().build()
WorkManager.getInstance(context).enqueue(myWorker)
LoadingScreen()
return
}
// handle finished worker
}
@Composable
fun LoadingScreen() {
// compose loading screen
}
}
I tested this code with single widget and it always shows loading screen and taskId
is always null even though workers run successfully. How to fix this problem?
So, the problem is in the
toMutablePreferences
, all of the examples I've seen used this method, however instead of saving new values to the same data store it creates a copy of data store which is not saved.The correct code should be: