Alexey Peschany
Alexey Peschany

Reputation: 11

Glance App Widget state not saved inside CoroutineWorker

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

Answers (1)

Alexey Peschany
Alexey Peschany

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

Related Questions