I am trying to implement a worker that updates my weather data every 1.5 hours. I am using PeriodicWorkRequestBuilder and have specified the time as shown in my code:
@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val workRequest = PeriodicWorkRequestBuilder<WeatherUpdateWorker>(
repeatInterval = 90,
repeatIntervalTimeUnit = TimeUnit.MINUTES,
).setBackoffCriteria(
backoffPolicy = BackoffPolicy.LINEAR,
duration = Duration.ofSeconds(15)
)
.build()
WorkManager.getInstance(applicationContext).enqueueUniquePeriodicWork(
"WeatherUpdateWork",
ExistingPeriodicWorkPolicy.KEEP,
workRequest
)
However, when I check Logcat, my worker logs show that it is being executing every 15 minutes. How do I fix this?
I have added logs to my worker to show the time it is being called:
@HiltWorker
class WeatherUpdateWorker @AssistedInject constructor(
private val api: WeatherService,
@Assisted val context: Context,
@Assisted workerParameters: WorkerParameters,
private val viewModel: WeatherViewModel
): CoroutineWorker(context, workerParameters) {
override suspend fun doWork(): Result {
try {
val response = api.getWeather()
viewModel.setWeatherResults(response)
val currentTime = System.currentTimeMillis()
saveLastExecutionTime(currentTime)
Log.d("WeatherWorker", "Success, ${currentTime}")
return Result.success()
} catch (e: Exception) {
Log.d("WeatherWorker", "Error")
return Result.retry()
}
}
private fun saveLastExecutionTime(currentTime: Long) {
val sharedPreferences = context.getSharedPreferences("weather_prefs", Context.MODE_PRIVATE)
sharedPreferences.edit().putLong("last_execution_time", currentTime).apply()
}
}
WorkerFactory:
@HiltAndroidApp
class Application : Application(), Configuration.Provider {
@Inject
lateinit var workerFactory: CustomWorkerFactory
override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setWorkerFactory(workerFactory)
.build()
}
class CustomWorkerFactory @Inject constructor(private val api: WeatherService, private val viewModel: WeatherViewModel): WorkerFactory() {
override fun createWorker(
appContext: Context,
workerClassName: String,
workerParameters: WorkerParameters
): ListenableWorker? = WeatherUpdateWorker(api, appContext, workerParameters, viewModel)
Most likely that because you are using ExistingPeriodicWorkPolicy.KEEP
that you have an existing PeriodicWorkRequestBuilder with a period of 15 minutes and your change to a period of 1.5 hours is being ignored as the documentation says for ExistingPeriodicWorkPolicy.KEEP
If there is existing pending (uncompleted) work with the same unique name, do nothing. Otherwise, insert the newly-specified work.
Best to use ExistingPeriodicWorkPolicy.REPLACE
or ExistingPeriodicWorkPolicy.UPDATE