Reputation: 11
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?
Upvotes: 1
Views: 1348
Reputation: 11
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:
updateAppWidgetState(
context = applicationContext,
glanceId = glanceId,
) { preferences ->
preferences.apply{
this[stringPreferencesKey(TASK_ID)] = id.toString()
}
}
Upvotes: 0