From 02456a148ef6dc6eacf7a74ad5ccf4389d7164b8 Mon Sep 17 00:00:00 2001 From: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com> Date: Mon, 3 Nov 2025 23:10:35 +0530 Subject: [PATCH] feat: android periodic work manager task --- .../immich/background/BackgroundEngineLock.kt | 2 +- .../background/BackgroundWorkerApiImpl.kt | 34 ++++++++++++++++--- .../immich/background/PeriodicWorker.kt | 16 +++++++++ 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 mobile/android/app/src/main/kotlin/app/alextran/immich/background/PeriodicWorker.kt diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundEngineLock.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundEngineLock.kt index b11b53bcde..bcd7eeee18 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundEngineLock.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundEngineLock.kt @@ -43,8 +43,8 @@ class BackgroundEngineLock(context: Context) : BackgroundWorkerLockApi, ImmichPl override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { super.onAttachedToEngine(binding) - checkAndEnforceBackgroundLock(binding.applicationContext) engineCount.incrementAndGet() + checkAndEnforceBackgroundLock(binding.applicationContext) Log.i(TAG, "Flutter engine attached. Attached Engines count: $engineCount") } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerApiImpl.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerApiImpl.kt index a78db3c5ea..bc0766bee5 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerApiImpl.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerApiImpl.kt @@ -5,8 +5,10 @@ import android.provider.MediaStore import android.util.Log import androidx.work.BackoffPolicy import androidx.work.Constraints +import androidx.work.ExistingPeriodicWorkPolicy import androidx.work.ExistingWorkPolicy -import androidx.work.OneTimeWorkRequest +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.PeriodicWorkRequestBuilder import androidx.work.WorkManager import io.flutter.embedding.engine.FlutterEngineCache import java.util.concurrent.TimeUnit @@ -18,6 +20,7 @@ class BackgroundWorkerApiImpl(context: Context) : BackgroundWorkerFgHostApi { override fun enable() { enqueueMediaObserver(ctx) + enqueuePeriodicWorker(ctx) } override fun saveNotificationMessage(title: String, body: String) { @@ -27,12 +30,14 @@ class BackgroundWorkerApiImpl(context: Context) : BackgroundWorkerFgHostApi { override fun configure(settings: BackgroundWorkerSettings) { BackgroundWorkerPreferences(ctx).updateSettings(settings) enqueueMediaObserver(ctx) + enqueuePeriodicWorker(ctx) } override fun disable() { WorkManager.getInstance(ctx).apply { cancelUniqueWork(OBSERVER_WORKER_NAME) cancelUniqueWork(BACKGROUND_WORKER_NAME) + cancelUniqueWork(PERIODIC_WORKER_NAME) } Log.i(TAG, "Cancelled background upload tasks") } @@ -40,6 +45,7 @@ class BackgroundWorkerApiImpl(context: Context) : BackgroundWorkerFgHostApi { companion object { private const val BACKGROUND_WORKER_NAME = "immich/BackgroundWorkerV1" private const val OBSERVER_WORKER_NAME = "immich/MediaObserverV1" + private const val PERIODIC_WORKER_NAME = "immich/PeriodicBackgroundWorkerV1" const val ENGINE_CACHE_KEY = "immich::background_worker::engine" @@ -55,7 +61,7 @@ class BackgroundWorkerApiImpl(context: Context) : BackgroundWorkerFgHostApi { setRequiresCharging(settings.requiresCharging) }.build() - val work = OneTimeWorkRequest.Builder(MediaObserver::class.java) + val work = OneTimeWorkRequestBuilder() .setConstraints(constraints) .build() WorkManager.getInstance(ctx) @@ -67,10 +73,30 @@ class BackgroundWorkerApiImpl(context: Context) : BackgroundWorkerFgHostApi { ) } + fun enqueuePeriodicWorker(ctx: Context) { + val settings = BackgroundWorkerPreferences(ctx).getSettings() + val constraints = Constraints.Builder().apply { + setRequiresCharging(settings.requiresCharging) + }.build() + + val work = + PeriodicWorkRequestBuilder( + 1, + TimeUnit.HOURS, + 15, + TimeUnit.MINUTES + ).setConstraints(constraints) + .build() + + WorkManager.getInstance(ctx) + .enqueueUniquePeriodicWork(PERIODIC_WORKER_NAME, ExistingPeriodicWorkPolicy.UPDATE, work) + + Log.i(TAG, "Enqueued periodic background worker with name: $PERIODIC_WORKER_NAME") + } + fun enqueueBackgroundWorker(ctx: Context) { val constraints = Constraints.Builder().setRequiresBatteryNotLow(true).build() - - val work = OneTimeWorkRequest.Builder(BackgroundWorker::class.java) + val work = OneTimeWorkRequestBuilder() .setConstraints(constraints) .setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 1, TimeUnit.MINUTES) .build() diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/PeriodicWorker.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/PeriodicWorker.kt new file mode 100644 index 0000000000..d4ecde9bbb --- /dev/null +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/PeriodicWorker.kt @@ -0,0 +1,16 @@ +package app.alextran.immich.background + +import android.content.Context +import android.util.Log +import androidx.work.Worker +import androidx.work.WorkerParameters + +class PeriodicWorker(context: Context, params: WorkerParameters) : Worker(context, params) { + private val ctx: Context = context.applicationContext + + override fun doWork(): Result { + Log.i("PeriodicWorker", "Periodic worker triggered, starting background worker") + BackgroundWorkerApiImpl.enqueueBackgroundWorker(ctx) + return Result.success() + } +}