fix(android): cancel only fetch-related WorkManager jobs when scheduling daily notification

Prevents a second notification (UUID alarm) with fallback or placeholder text by
cancelling pending prefetch/fetch work when the user schedules or reschedules.
cleanupExistingNotificationSchedules only cancels alarms for DB schedule IDs;
alarms from DailyNotificationFetchWorker use a UUID and were never cancelled.

Add ScheduleHelper.cancelFetchRelatedWorkManagerJobs() to cancel only the
prefetch and daily_notification_fetch tags (not display, dismiss, or maintenance).
Call it after cleanup and before scheduleDailyNotification. Future fetched-content
flows can use distinct WorkManager tags and will not be affected by this path.
This commit is contained in:
Jose Olarte III
2026-03-02 16:41:14 +08:00
parent cff7b659dc
commit c36781e440

View File

@@ -1137,6 +1137,14 @@ open class DailyNotificationPlugin : Plugin() {
Log.i(TAG, "scheduleDailyNotification: No cleanup needed - existing schedule will be updated via upsert: $scheduleId") Log.i(TAG, "scheduleDailyNotification: No cleanup needed - existing schedule will be updated via upsert: $scheduleId")
} }
// Cancel only fetch-related WorkManager jobs so they cannot create a second (UUID) alarm
// with fallback or placeholder text. Does not cancel display/dismiss; future fetched-content
// flows should use distinct tags so they are not affected.
val workCancelled = ScheduleHelper.cancelFetchRelatedWorkManagerJobs(context)
if (workCancelled) {
Log.i(TAG, "scheduleDailyNotification: Cancelled pending prefetch/fetch WorkManager jobs")
}
val config = UserNotificationConfig( val config = UserNotificationConfig(
enabled = true, enabled = true,
schedule = cronExpression, schedule = cronExpression,
@@ -2846,6 +2854,27 @@ object ScheduleHelper {
} }
} }
/**
* Cancel only WorkManager jobs that can create a second (UUID) alarm for the static-reminder path:
* prefetch and daily_notification_fetch. Does not cancel display, dismiss, or maintenance.
* Use this when handling scheduleDailyNotification so pending prefetch does not run and create
* a duplicate alarm; future fetched-content flows should use distinct tags so they are not affected.
*
* @param context Application context
* @return true if cancellation was successful
*/
suspend fun cancelFetchRelatedWorkManagerJobs(context: Context): Boolean {
return try {
val workManager = WorkManager.getInstance(context)
workManager.cancelAllWorkByTag("prefetch")
workManager.cancelAllWorkByTag("daily_notification_fetch")
true
} catch (e: Exception) {
Log.w("ScheduleHelper", "Failed to cancel fetch-related WorkManager jobs", e)
false
}
}
/** /**
* Cancel all WorkManager jobs by tags * Cancel all WorkManager jobs by tags
* *