diff --git a/app/src/main/java/org/tasks/preferences/Preferences.kt b/app/src/main/java/org/tasks/preferences/Preferences.kt index cd0896218..703f3759d 100644 --- a/app/src/main/java/org/tasks/preferences/Preferences.kt +++ b/app/src/main/java/org/tasks/preferences/Preferences.kt @@ -6,12 +6,10 @@ import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.content.pm.PackageManager -import android.media.RingtoneManager import android.net.Uri import android.os.Binder import androidx.compose.material3.DisplayMode import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.core.app.NotificationCompat import androidx.core.net.toUri import androidx.documentfile.provider.DocumentFile import androidx.preference.PreferenceManager @@ -30,8 +28,6 @@ import org.tasks.extensions.Context.getResourceUri import org.tasks.kmp.org.tasks.themes.ColorProvider.BLUE_500 import org.tasks.themes.ThemeBase import org.tasks.time.DateTime -import org.tasks.time.DateTimeUtils2.currentTimeMillis -import org.tasks.time.ONE_WEEK import timber.log.Timber import java.io.File import java.net.URI diff --git a/app/src/main/java/org/tasks/widget/AppWidgetManager.kt b/app/src/main/java/org/tasks/widget/AppWidgetManager.kt index a55a3a62b..314a2d3e6 100644 --- a/app/src/main/java/org/tasks/widget/AppWidgetManager.kt +++ b/app/src/main/java/org/tasks/widget/AppWidgetManager.kt @@ -1,12 +1,15 @@ 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.launch import kotlinx.coroutines.withContext import org.tasks.R @@ -25,23 +28,45 @@ class AppWidgetManager @Inject constructor( ?.getAppWidgetIds(ComponentName(context, TasksWidget::class.java)) ?: intArrayOf() - fun reconfigureWidgets(vararg appWidgetIds: Int) = scope.launch(Dispatchers.IO) { + fun reconfigureWidgets(vararg appWidgetIds: Int) = scope.launch { Timber.d("reconfigureWidgets(${appWidgetIds.joinToString()})") + + val ids = appWidgetIds.takeIf { it.isNotEmpty() } ?: widgetIds + val intent = Intent(context, TasksWidget::class.java) - intent.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE - intent.putExtra( - AppWidgetManager.EXTRA_APPWIDGET_IDS, - appWidgetIds.takeIf { it.isNotEmpty() } ?: widgetIds) - context.sendBroadcast(intent) + .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 + ) } - fun updateWidgets() = scope.launch(Dispatchers.IO) { + fun updateWidgets() = scope.launch { val appWidgetIds = widgetIds - Timber.d("updateWidgets: ${appWidgetIds.joinToString()}") - withContext(Dispatchers.Main) { - appWidgetManager?.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.list_view) - } + Timber.d("updateWidgets: ${appWidgetIds.joinToString { it.toString() }}") + notifyAppWidgetViewDataChanged(appWidgetIds) } fun exists(id: Int) = appWidgetManager?.getAppWidgetInfo(id) != null -} \ No newline at end of file + + private suspend fun notifyAppWidgetViewDataChanged(appWidgetIds: IntArray) = withContext(Dispatchers.Main) { + appWidgetManager?.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.list_view) + } +} diff --git a/app/src/main/java/org/tasks/widget/TasksWidget.kt b/app/src/main/java/org/tasks/widget/TasksWidget.kt index ca846fb85..b49cff099 100644 --- a/app/src/main/java/org/tasks/widget/TasksWidget.kt +++ b/app/src/main/java/org/tasks/widget/TasksWidget.kt @@ -5,10 +5,10 @@ import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetProvider import android.content.Context import android.content.Intent -import android.net.Uri import android.os.Bundle import android.view.View import android.widget.RemoteViews +import androidx.core.net.toUri import com.todoroo.andlib.utility.AndroidUtilities.atLeastS import com.todoroo.astrid.activity.MainActivity.Companion.FINISH_AFFINITY import dagger.hilt.android.AndroidEntryPoint @@ -35,13 +35,11 @@ class TasksWidget : AppWidgetProvider() { @Inject @ApplicationContext lateinit var context: Context override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { - appWidgetIds.forEach { appWidgetId -> + Timber.d("onUpdate appWidgetIds=${appWidgetIds.joinToString { it.toString() }}") + appWidgetIds.forEach { id -> try { - val options = appWidgetManager.getAppWidgetOptions(appWidgetId) - appWidgetManager.updateAppWidget( - appWidgetId, - createWidget(context, appWidgetId, options) - ) + val options = appWidgetManager.getAppWidgetOptions(id) + appWidgetManager.updateAppWidget(id, createWidget(context, id, options)) } catch (e: Exception) { Timber.e(e) } @@ -54,10 +52,12 @@ class TasksWidget : AppWidgetProvider() { appWidgetId: Int, newOptions: Bundle ) { + Timber.d("onAppWidgetOptionsChanged appWidgetId=$appWidgetId") appWidgetManager.updateAppWidget( appWidgetId, createWidget(context, appWidgetId, newOptions) ) + appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.list_view) } private fun createWidget(context: Context, id: Int, options: Bundle): RemoteViews { @@ -69,6 +69,8 @@ class TasksWidget : AppWidgetProvider() { val filter = runBlocking { defaultFilterProvider.getFilterFromPreference(widgetPreferences.filterId) } + Timber.d("createWidget id=$id filter=$filter") + return RemoteViews(context.packageName, R.layout.scrollable_widget).apply { if (settings.showHeader) { setViewVisibility(R.id.widget_header, View.VISIBLE) @@ -87,11 +89,12 @@ class TasksWidget : AppWidgetProvider() { opacity = widgetPreferences.footerOpacity, ) setOnClickPendingIntent(R.id.empty_view, getOpenListIntent(context, filter, id)) - val cacheBuster = Uri.parse("tasks://widget/" + currentTimeMillis()) + val cacheBuster = "tasks://widget/${currentTimeMillis()}".toUri() setRemoteAdapter( 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)) @@ -232,4 +235,4 @@ class TasksWidget : AppWidgetProvider() { private const val COMPACT_MAX = 275 private const val FLAGS = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP } -} \ No newline at end of file +} diff --git a/app/src/main/java/org/tasks/widget/TasksWidgetAdapter.kt b/app/src/main/java/org/tasks/widget/TasksWidgetAdapter.kt index 4ff1cdde7..8f4d00d94 100644 --- a/app/src/main/java/org/tasks/widget/TasksWidgetAdapter.kt +++ b/app/src/main/java/org/tasks/widget/TasksWidgetAdapter.kt @@ -13,6 +13,7 @@ import org.tasks.markdown.MarkdownProvider import org.tasks.preferences.DefaultFilterProvider import org.tasks.preferences.Preferences import org.tasks.tasklist.HeaderFormatter +import timber.log.Timber import javax.inject.Inject @AndroidEntryPoint @@ -32,6 +33,7 @@ class TasksWidgetAdapter : RemoteViewsService() { val filter = runBlocking { defaultFilterProvider.getFilterFromPreference(widgetPreferences.filterId) } + Timber.d("onGetViewFactory $filter") return TasksWidgetViewFactory( subtasksHelper, widgetPreferences, diff --git a/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt b/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt index e169f5e8b..c9f2871d5 100644 --- a/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt +++ b/app/src/main/java/org/tasks/widget/TasksWidgetViewFactory.kt @@ -66,9 +66,12 @@ internal class TasksWidgetViewFactory( chipProvider.isDark = settings.isDark } - override fun onCreate() {} + override fun onCreate() { + Timber.d("onCreate widgetId:$widgetId filter:$filter") + } override fun onDataSetChanged() { + Timber.v("onDataSetChanged $filter") runBlocking { val collapsed = widgetPreferences.collapsed tasks = SectionedDataSource( @@ -87,7 +90,9 @@ internal class TasksWidgetViewFactory( } } - override fun onDestroy() {} + override fun onDestroy() { + Timber.d("onDestroy widgetId:$widgetId") + } override fun getCount() = tasks.size.coerceAtMost(taskLimit)