feat: [#27] sync CalDAV en arrière-plan (WorkManager PeriodicWork, SyncScheduler, reprise au démarrage)
This commit is contained in:
@@ -3,14 +3,17 @@ package com.planify.mobile.data.notification
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.planify.mobile.data.sync.SyncScheduler
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class BootReceiver : BroadcastReceiver() {
|
||||
|
||||
@Inject lateinit var syncScheduler: SyncScheduler
|
||||
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action != Intent.ACTION_BOOT_COMPLETED) return
|
||||
// TODO #14 : replanifier toutes les alarmes depuis la base de données
|
||||
// Inject ReminderScheduler + ReminderRepository et rejouer tous les rappels actifs
|
||||
syncScheduler.schedule()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.planify.mobile.data.sync
|
||||
|
||||
import android.content.Context
|
||||
import androidx.hilt.work.HiltWorker
|
||||
import androidx.work.CoroutineWorker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.planify.mobile.data.caldav.CalDavSyncManager
|
||||
import com.planify.mobile.data.caldav.SyncResult
|
||||
import com.planify.mobile.domain.repository.SourceRepository
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
@HiltWorker
|
||||
class CalDavSyncWorker @AssistedInject constructor(
|
||||
@Assisted context: Context,
|
||||
@Assisted params: WorkerParameters,
|
||||
private val sourceRepository: SourceRepository,
|
||||
private val syncManager: CalDavSyncManager,
|
||||
) : CoroutineWorker(context, params) {
|
||||
|
||||
override suspend fun doWork(): Result {
|
||||
val sources = sourceRepository.getCaldavSources()
|
||||
if (sources.isEmpty()) return Result.success()
|
||||
|
||||
var hasError = false
|
||||
sources.forEach { source ->
|
||||
val result = syncManager.incrementalSync(source)
|
||||
if (result is SyncResult.Failure) hasError = true
|
||||
}
|
||||
|
||||
return if (hasError) Result.retry() else Result.success()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val WORK_NAME = "caldav_periodic_sync"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.planify.mobile.data.sync
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.Constraints
|
||||
import androidx.work.ExistingPeriodicWorkPolicy
|
||||
import androidx.work.NetworkType
|
||||
import androidx.work.PeriodicWorkRequestBuilder
|
||||
import androidx.work.WorkManager
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class SyncScheduler @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
) {
|
||||
private val workManager = WorkManager.getInstance(context)
|
||||
|
||||
fun schedule(intervalMinutes: Long = 30) {
|
||||
val constraints = Constraints.Builder()
|
||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
.build()
|
||||
|
||||
val request = PeriodicWorkRequestBuilder<CalDavSyncWorker>(
|
||||
repeatInterval = intervalMinutes,
|
||||
repeatIntervalTimeUnit = TimeUnit.MINUTES,
|
||||
)
|
||||
.setConstraints(constraints)
|
||||
.build()
|
||||
|
||||
workManager.enqueueUniquePeriodicWork(
|
||||
CalDavSyncWorker.WORK_NAME,
|
||||
ExistingPeriodicWorkPolicy.UPDATE,
|
||||
request,
|
||||
)
|
||||
}
|
||||
|
||||
fun cancel() {
|
||||
workManager.cancelUniqueWork(CalDavSyncWorker.WORK_NAME)
|
||||
}
|
||||
|
||||
fun syncNow() {
|
||||
val request = androidx.work.OneTimeWorkRequestBuilder<CalDavSyncWorker>()
|
||||
.setConstraints(
|
||||
Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()
|
||||
)
|
||||
.build()
|
||||
workManager.enqueue(request)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user