如何实现因不活动而导致的超时操作
How to implement a timeout action due to inactivity
假设我有一个动作要在用户不触摸屏幕一段时间后执行。我如何实现一个计时器,它在超时时执行操作,但在每次用户触摸屏幕时重新开始?
我搜索了几个答案,但没有找到像我想要的解决方案一样简单的解决方案。这是对我有用的:
我使用了在 onCreate() 中启动并在 onDestroy() 中取消的 onUserInteraction() function, which is called every time the user touches the screen. I declared a CountDownTimer。每次调用 onUserInteraction() 时,CountDownTimer 都会被取消、重置,然后再次启动。当 CountDownTimer 完成时,执行操作。
package com.example.inactivityapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.CountDownTimer
import android.util.Log
import android.widget.Toast
private val TAG = InactivityActivity::class.java.simpleName
private const val INACTIVITY_SECONDS: Int = 5
class InactivityActivity : AppCompatActivity() {
var inactivitySeconds = INACTIVITY_SECONDS
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_inactivity)
inactivityCountDownTimer.start()
}
override fun onDestroy() {
super.onDestroy()
inactivityCountDownTimer.cancel()
}
override fun onUserInteraction() {
super.onUserInteraction()
Log.i(TAG, "user interaction")
inactivityCountDownTimer.cancel()
inactivitySeconds = INACTIVITY_SECONDS
inactivityCountDownTimer.start()
}
var inactivityCountDownTimer =
object : CountDownTimer(inactivitySeconds * 1000.toLong(), 1000) {
override fun onTick(millisUntilFinished: Long) {
Log.i(TAG, inactivitySeconds.toString())
inactivitySeconds--
}
override fun onFinish() {
Toast.makeText(
this@InactivityActivity,
"Activity Timeout: Perform timeout task",
Toast.LENGTH_LONG
).show()
Log.i(TAG, "activity timeout")
}
}
}
这是一个未经测试的协程想法:
private const val INACTIVITY_SECONDS: Int = 5
abstract class InactivityActivity : AppCompatActivity() {
private val counterScope = CoroutineScope(Dispatchers.Main)
private fun restartCountDown() {
counterScope.cancel()
counterScope.launch {
delay(INACTIVITY_SECONDS * 1000L)
onInactivity()
}
}
protected abstract fun onInactivity()
override fun onPause() {
super.onPause()
counterScope.cancel()
}
override fun onResume() {
super.onResume()
restartCountDown()
}
override fun onUserInteraction() {
super.onUserInteraction()
restartCountDown()
}
}
假设我有一个动作要在用户不触摸屏幕一段时间后执行。我如何实现一个计时器,它在超时时执行操作,但在每次用户触摸屏幕时重新开始?
我搜索了几个答案,但没有找到像我想要的解决方案一样简单的解决方案。这是对我有用的:
我使用了在 onCreate() 中启动并在 onDestroy() 中取消的 onUserInteraction() function, which is called every time the user touches the screen. I declared a CountDownTimer。每次调用 onUserInteraction() 时,CountDownTimer 都会被取消、重置,然后再次启动。当 CountDownTimer 完成时,执行操作。
package com.example.inactivityapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.CountDownTimer
import android.util.Log
import android.widget.Toast
private val TAG = InactivityActivity::class.java.simpleName
private const val INACTIVITY_SECONDS: Int = 5
class InactivityActivity : AppCompatActivity() {
var inactivitySeconds = INACTIVITY_SECONDS
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_inactivity)
inactivityCountDownTimer.start()
}
override fun onDestroy() {
super.onDestroy()
inactivityCountDownTimer.cancel()
}
override fun onUserInteraction() {
super.onUserInteraction()
Log.i(TAG, "user interaction")
inactivityCountDownTimer.cancel()
inactivitySeconds = INACTIVITY_SECONDS
inactivityCountDownTimer.start()
}
var inactivityCountDownTimer =
object : CountDownTimer(inactivitySeconds * 1000.toLong(), 1000) {
override fun onTick(millisUntilFinished: Long) {
Log.i(TAG, inactivitySeconds.toString())
inactivitySeconds--
}
override fun onFinish() {
Toast.makeText(
this@InactivityActivity,
"Activity Timeout: Perform timeout task",
Toast.LENGTH_LONG
).show()
Log.i(TAG, "activity timeout")
}
}
}
这是一个未经测试的协程想法:
private const val INACTIVITY_SECONDS: Int = 5
abstract class InactivityActivity : AppCompatActivity() {
private val counterScope = CoroutineScope(Dispatchers.Main)
private fun restartCountDown() {
counterScope.cancel()
counterScope.launch {
delay(INACTIVITY_SECONDS * 1000L)
onInactivity()
}
}
protected abstract fun onInactivity()
override fun onPause() {
super.onPause()
counterScope.cancel()
}
override fun onResume() {
super.onResume()
restartCountDown()
}
override fun onUserInteraction() {
super.onUserInteraction()
restartCountDown()
}
}