Runnable RemoveCallbacks, похоже, не работает, поэтому новый Runnable не запускаетсяAndroid

Форум для тех, кто программирует под Android
Anonymous
Runnable RemoveCallbacks, похоже, не работает, поэтому новый Runnable не запускается

Сообщение Anonymous »

Я пытаюсь создать простой трекер экрана, который также отслеживает ваш экран, когда он выключен. По какой-то причине кажется, что screenTimeRunnable не хочет останавливаться, и поэтому offScreenTimeRunnable никогда не получает возможности обновить offScreenTime. Я точно не знаю, в этом ли дело.

Код: Выделить всё

interface ScreenTimeUpdateListener {
fun onScreenTimeUpdated(screenTime: Long, offScreenTime: Long)
}
class ScreenTimeReceiver : BroadcastReceiver() {
var listener: ScreenTimeUpdateListener? = null

private var screenOn = true
private var screenTime = 0L
private var offScreenTime = 0L
private val handler = Handler(Looper.getMainLooper())
private val updateInterval = 1000L

private val screenTimeRunnable = object : Runnable {
override fun run() {
if (screenOn) {
screenTime += updateInterval
listener?.onScreenTimeUpdated(screenTime, offScreenTime)
}
handler.postDelayed(this, updateInterval)
}
}

private val offScreenTimeRunnable = object : Runnable {
override fun run() {
if (!screenOn) {
offScreenTime += updateInterval
listener?.onScreenTimeUpdated(screenTime, offScreenTime)
}
handler.postDelayed(this, updateInterval)
}
}

override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
Intent.ACTION_SCREEN_ON -> {
Log.d("ScreenTimeReceiver", "Screen ON detected")
screenOn = true
Log.d("ScreenTimeReceiver", "screenOn set to: $screenOn")
resetHandler()
}
Intent.ACTION_SCREEN_OFF ->  {
Log.d("ScreenTimeReceiver", "Screen OFF detected")
screenOn = false
Log.d("ScreenTimeReceiver", "screenOn set to: $screenOn")
resetHandler()
}
}
}

private fun resetHandler() {
handler.removeCallbacks(screenTimeRunnable)
handler.removeCallbacks(offScreenTimeRunnable)

if (screenOn) {
Log.d("ScreenTimeReceiver", "Posting screenTimeRunnable")
handler.post(screenTimeRunnable)
} else {
Log.d("ScreenTimeReceiver", "Posting offScreenTimeRunnable")
handler.post(offScreenTimeRunnable)
}
}

fun startTracking() {
resetHandler()
}

fun stopTracking() {
handler.removeCallbacksAndMessages(null)
}
}
Методы, которые улавливают эти обновления в модели представления:

Код: Выделить всё

override fun onScreenTimeUpdated(screenTime: Long, offScreenTime: Long) {
this.screenTime = screenTime
this.offScreenTime = offScreenTime
points = (this.offScreenTime / 1000).toInt()
Log.d("RealityCheckViewModel", "Screen time: ${this.screenTime}, Off screen time: ${this.offScreenTime}, Points: $points")
}
Журналы:

Код: Выделить всё

2024-10-16 14:14:08.183  D  Posting screenTimeRunnable
2024-10-16 14:14:08.349  D  Screen time: 1000, Off screen time: 0, Points: 0
2024-10-16 14:14:08.353  D  Posting screenTimeRunnable
2024-10-16 14:14:08.386  D  Screen time: 2000, Off screen time: 0, Points: 0
2024-10-16 14:14:09.388  D  Screen time: 3000, Off screen time: 0, Points: 0
2024-10-16 14:14:10.390  D  Screen time: 4000, Off screen time: 0, Points: 0
2024-10-16 14:14:11.393  D  Screen time: 5000, Off screen time: 0, Points: 0
2024-10-16 14:14:12.396  D  Screen time: 6000, Off screen time: 0, Points: 0
2024-10-16 14:14:13.400  D  Screen time: 7000, Off screen time: 0, Points: 0
2024-10-16 14:14:13.827  D  visibilityChanged oldVisibility=true newVisibility=false
2024-10-16 14:14:13.922  D  endAllActiveAnimators on 0x73c188c1b040 (UnprojectedRipple) with handle 0x73c058c54aa0
2024-10-16 14:14:14.293  D  Screen OFF detected
2024-10-16 14:14:14.293  D  screenOn set to: false
2024-10-16 14:14:14.293  D  Posting offScreenTimeRunnable
2024-10-16 14:14:14.409  D  Screen time: 8000, Off screen time: 0, Points: 0
2024-10-16 14:14:15.412  D  Screen time: 9000, Off screen time: 0, Points: 0
2024-10-16 14:14:16.414  D  Screen time: 10000, Off screen time: 0, Points: 0
2024-10-16 14:14:17.416  D  Screen time: 11000, Off screen time: 0, Points: 0
2024-10-16 14:14:18.417  D  Screen time: 12000, Off screen time: 0, Points: 0
2024-10-16 14:14:19.419  D  Screen time: 13000, Off screen time: 0, Points: 0
2024-10-16 14:14:20.238  D  Screen ON detected
2024-10-16 14:14:20.239  D  screenOn set to: true
2024-10-16 14:14:20.243  D  Posting screenTimeRunnable
2024-10-16 14:14:20.424  D  Screen time: 14000, Off screen time: 0, Points: 0
2024-10-16 14:14:21.426  D  Screen time: 15000, Off screen time: 0, Points: 0
2024-10-16 14:14:22.429  D  Screen time: 16000, Off screen time: 0, Points: 0
2024-10-16 14:14:23.432  D  Screen time: 17000, Off screen time: 0, Points: 0
2024-10-16 14:14:24.433  D  Screen time: 18000, Off screen time: 0, Points: 0
Я уже пробовал использовать handler.removeCallbacksAndMessages(null) как отдельно, так и с тем, что у меня уже есть.
Я ожидаю screenTime, чтобы остановить приращение, когда offScreenTime выключен, и offScreenTime, чтобы начать приращение.

Подробнее здесь: https://stackoverflow.com/questions/790 ... -not-start

Вернуться в «Android»