Android WorkManager Check Next Execution Time

December 4, 2019

We can get WorkInfo by

  • Unique Work Name: WorkManager.getWorkInfosForUniqueWork
  • ID
  • Tag

But we can only check for state, but we won’t know when it will run next.

I run work manager

  • with unique work name: I use this to query WorkInfo at later stage
  • I add a timestamp tag to the work request, to indicate what time this work is expected to run
val workManager = WorkManager.getInstance(context)

val workName = "reminder1"
val delayInSeconds = 60*5
val timestamp = LocalDateTime.now().toEpochSecond()!! + delayInSeconds

val workRequest = OneTimeWorkRequestBuilder<ReminderWorker>()
    .setInitialDelay(delayInSeconds, TimeUnit.SECONDS)
    // .setInputData(data)
    .addTag("time:$timestamp")
    .build()

workManager.enqueueUniqueWork(workName, ExistingWorkPolicy.REPLACE, workRequest)
fun LocalDateTime.toEpochSecond(zone: ZoneId = ZoneId.systemDefault()) = atZone(zone)?.toEpochSecond()

Now I can check when this work is expected to run

val workName = "reminder1"

val workInfos = workManager.getWorkInfosForUniqueWork(workName).await()
if (workInfos.size == 1) {
    val workInfo = workInfos[0]
    if (!workInfo.state.isFinished) {
        val re = "time:(\\d+)".toRegex()
        val timeTag = workInfo.tags.find { it.startsWith("time:") }

        if (timeTag != null) {
            val timestamp = re.find(timeTag)?.groupValues?.get(1)?.toLong()
            if (timestamp != null) {
                val now = LocalDateTime.now().toEpochSecond()!!
                if (now > timestamp + 60*5) {
                    Timber.i("$workName expired ${now - timestamp}s")
                }
                else {
                    Timber.i("$workName will run in ${timestamp - now}s")
                }
            }
            else {
                Timber.i("$workName timeTag extract fail")
            }
        }
        else {
            Timber.i("$workName missing timeTag")
        }
    }
    else {
        Timber.i("$workName isFinished")
    }
}
else {
    Timber.i("$workName WorkInfo missing=${workInfos.size}")
}
This work is licensed under a
Creative Commons Attribution-NonCommercial 4.0 International License.