I'm developing timer app like focus to do and to achieve this I used a foreground service and timer task within it.
now when when device is screen off timer task no longer emitted.
and after a little when device screen turns on timer task emits immediately
my timer interval is set to 100 ms, but updating the UI every 1 second. Also the app was excluded from battery saving.
my custom timer task class:
abstract class CustomTimer @JvmOverloads constructor(
private val totalTime: Long,
private val interval: Long,
private val delay: Long = 0
) :
Timer("PreciseCountdownTimer", true) {
private var task: TimerTask
private var startTime: Long = -1
private var timeLeft: Long = 0
private var restart = false
private var wasCancelled = false
private var isDisposed = false
private var wasStarted = false
init {
task = buildTask(totalTime)
isDisposed = false
}
private fun buildTask(totalTime: Long): TimerTask {
return object : TimerTask() {
override fun run() {
if (startTime < 0 || restart) {
startTime = scheduledExecutionTime()
timeLeft = totalTime
restart = false
} else {
timeLeft = totalTime - (scheduledExecutionTime() - startTime)
if (timeLeft <= 0) {
this.cancel()
wasCancelled = true
startTime = -1
Log.d("shower", "run: ")
onFinished()
return
}
}
onTick(timeLeft)
}
}
}
fun getTimeLeft() = timeLeft
fun start() {
wasStarted = true
isDisposed = false
this.scheduleAtFixedRate(task, delay, interval)
}
fun stop() {
wasCancelled = true
task.cancel()
onStop()
}
fun restart() {
if (!wasStarted) {
start()
} else if (wasCancelled) {
wasCancelled = false
task = buildTask(totalTime)
start()
} else {
restart = true
}
}
fun isDisposed() = isDisposed
fun pause() {
wasCancelled = true
task.cancel()
onPaused()
}
fun updateWithNewTime(time : Long){
task.cancel()
task = buildTask(time)
startTime = -1
start()
}
fun resume() {
wasCancelled = false
isDisposed = false
task = buildTask(timeLeft)
startTime = -1
start()
onResumed()
}
// Call this when there's no further use for this timer
fun dispose() {
this.cancel()
this.purge()
isDisposed = true
}
abstract fun onTick(timeLeft: Long)
abstract fun onFinished()
abstract fun onPaused()
abstract fun onResumed()
abstract fun onStop()
}
I created log file which prove my assertion to timer not working in sleep mode. It is not emitted from second 3 until second 16 and then emits very fast in second 16 and 17... log is updated every 1 second.
