From 52848a53082a683c9dd9962cd11b2edf1839cd72 Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Sat, 4 Oct 2025 04:02:42 -0500 Subject: [PATCH] Attempt to fix flashing widgets --- .../main/java/org/tasks/TasksApplication.kt | 12 ----- .../tasks/receivers/ScreenUnlockReceiver.kt | 19 -------- .../java/org/tasks/widget/AppWidgetManager.kt | 47 +++++++++---------- .../main/java/org/tasks/widget/TasksWidget.kt | 2 - 4 files changed, 21 insertions(+), 59 deletions(-) delete mode 100644 app/src/main/java/org/tasks/receivers/ScreenUnlockReceiver.kt diff --git a/app/src/main/java/org/tasks/TasksApplication.kt b/app/src/main/java/org/tasks/TasksApplication.kt index 0ba4c37bf..3b739f78a 100644 --- a/app/src/main/java/org/tasks/TasksApplication.kt +++ b/app/src/main/java/org/tasks/TasksApplication.kt @@ -38,7 +38,6 @@ import org.tasks.location.GeofenceApi import org.tasks.opentasks.OpenTaskContentObserver import org.tasks.preferences.Preferences import org.tasks.receivers.RefreshReceiver -import org.tasks.receivers.ScreenUnlockReceiver import org.tasks.scheduling.NotificationSchedulerIntentService import org.tasks.sync.SyncAdapters import org.tasks.themes.ThemeBase @@ -142,7 +141,6 @@ class TasksApplication : Application(), Configuration.Provider { geofenceApi.get().registerAll() appWidgetManager.get().reconfigureWidgets() CaldavSynchronizer.registerFactories() - registerScreenUnlockReceiver() } override val workManagerConfiguration: Configuration @@ -167,16 +165,6 @@ class TasksApplication : Application(), Configuration.Provider { } } - private fun registerScreenUnlockReceiver() { - registerReceiver( - ScreenUnlockReceiver(appWidgetManager.get()), - IntentFilter().apply { - addAction(Intent.ACTION_USER_PRESENT) - addAction(Intent.ACTION_SCREEN_ON) - } - ) - } - companion object { @Suppress("KotlinConstantConditions") const val IS_GOOGLE_PLAY = BuildConfig.FLAVOR == "googleplay" diff --git a/app/src/main/java/org/tasks/receivers/ScreenUnlockReceiver.kt b/app/src/main/java/org/tasks/receivers/ScreenUnlockReceiver.kt deleted file mode 100644 index ae46164eb..000000000 --- a/app/src/main/java/org/tasks/receivers/ScreenUnlockReceiver.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.tasks.receivers - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent -import org.tasks.widget.AppWidgetManager -import timber.log.Timber - -class ScreenUnlockReceiver(private val appWidgetManager: AppWidgetManager) : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - when (intent.action) { - Intent.ACTION_USER_PRESENT, - Intent.ACTION_SCREEN_ON -> { - Timber.d("refreshing widgets: ${intent.action}") - appWidgetManager.updateWidgets() - } - } - } -} diff --git a/app/src/main/java/org/tasks/widget/AppWidgetManager.kt b/app/src/main/java/org/tasks/widget/AppWidgetManager.kt index 314a2d3e6..3fb2bcfca 100644 --- a/app/src/main/java/org/tasks/widget/AppWidgetManager.kt +++ b/app/src/main/java/org/tasks/widget/AppWidgetManager.kt @@ -1,18 +1,20 @@ package org.tasks.widget -import android.app.Activity import android.appwidget.AppWidgetManager -import android.content.BroadcastReceiver import android.content.ComponentName import android.content.Context import android.content.Intent import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.consumeAsFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.tasks.R +import org.tasks.compose.throttleLatest import org.tasks.injection.ApplicationScope import timber.log.Timber import javax.inject.Inject @@ -22,6 +24,19 @@ class AppWidgetManager @Inject constructor( @ApplicationScope private val scope: CoroutineScope, ) { private val appWidgetManager: AppWidgetManager? = AppWidgetManager.getInstance(context) + private val updateChannel = Channel(Channel.CONFLATED) + + init { + updateChannel + .consumeAsFlow() + .throttleLatest(1000) + .onEach { + val appWidgetIds = widgetIds + Timber.d("updateWidgets: ${appWidgetIds.joinToString { it.toString() }}") + notifyAppWidgetViewDataChanged(appWidgetIds) + } + .launchIn(scope) + } val widgetIds: IntArray get() = appWidgetManager @@ -37,31 +52,11 @@ class AppWidgetManager @Inject constructor( .putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids) .apply { action = AppWidgetManager.ACTION_APPWIDGET_UPDATE } - context.sendOrderedBroadcast( - intent, - null, - object : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - scope.launch { - Timber.d("Update widgets after reconfigure: ${appWidgetIds.joinToString { it.toString() }}") - // I don't like it, but this seems to give Android enough time to update - // the cache, and I don't have time to rewrite this in Glance right now - delay(100) - notifyAppWidgetViewDataChanged(ids) - } - } - }, - null, - Activity.RESULT_OK, - null, - null - ) + context.sendBroadcast(intent) } - fun updateWidgets() = scope.launch { - val appWidgetIds = widgetIds - Timber.d("updateWidgets: ${appWidgetIds.joinToString { it.toString() }}") - notifyAppWidgetViewDataChanged(appWidgetIds) + fun updateWidgets() { + updateChannel.trySend(Unit) } fun exists(id: Int) = appWidgetManager?.getAppWidgetInfo(id) != null diff --git a/app/src/main/java/org/tasks/widget/TasksWidget.kt b/app/src/main/java/org/tasks/widget/TasksWidget.kt index b49cff099..d6f301e1e 100644 --- a/app/src/main/java/org/tasks/widget/TasksWidget.kt +++ b/app/src/main/java/org/tasks/widget/TasksWidget.kt @@ -57,7 +57,6 @@ class TasksWidget : AppWidgetProvider() { appWidgetId, createWidget(context, appWidgetId, newOptions) ) - appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view) } private fun createWidget(context: Context, id: Int, options: Bundle): RemoteViews { @@ -94,7 +93,6 @@ class TasksWidget : AppWidgetProvider() { R.id.list_view, Intent(context, TasksWidgetAdapter::class.java) .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id) - .putExtra("extra_cache_buster", cacheBuster) .setData(cacheBuster) ) setPendingIntentTemplate(R.id.list_view, getPendingIntentTemplate(context))