【发布时间】:2010-11-02 05:43:28
【问题描述】:
在我的应用程序中有三个活动 A -> B -> C -> A。我想检测应用程序的空闲时间,以便在 15 分钟后无论活动如何都会弹出一条消息。实现这一点的最佳方法是什么。
【问题讨论】:
标签: android
在我的应用程序中有三个活动 A -> B -> C -> A。我想检测应用程序的空闲时间,以便在 15 分钟后无论活动如何都会弹出一条消息。实现这一点的最佳方法是什么。
【问题讨论】:
标签: android
我会这样做:
用于存储控制空闲时间的全局线程的类
public class ControlApplication extends Application
{
private static final String TAG=ControlApplication.class.getName();
private Waiter waiter; //Thread which controls idle time
// only lazy initializations here!
@Override
public void onCreate()
{
super.onCreate();
Log.d(TAG, "Starting application"+this.toString());
waiter=new Waiter(15*60*1000); //15 mins
waiter.start();
}
public void touch()
{
waiter.touch();
}
}
将成为您所有活动的父级的类
public class ControlActivity extends Activity
{
private static final String TAG=ControlActivity.class.getName();
/**
* Gets reference to global Application
* @return must always be type of ControlApplication! See AndroidManifest.xml
*/
public ControlApplication getApp()
{
return (ControlApplication )this.getApplication();
}
@Override
public void onUserInteraction()
{
super.onUserInteraction();
getApp().touch();
Log.d(TAG, "User interaction to "+this.toString());
}
}
最后是线程本身
public class Waiter extends Thread
{
private static final String TAG=Waiter.class.getName();
private long lastUsed;
private long period;
private boolean stop;
public Waiter(long period)
{
this.period=period;
stop=false;
}
public void run()
{
long idle=0;
this.touch();
do
{
idle=System.currentTimeMillis()-lastUsed;
Log.d(TAG, "Application is idle for "+idle +" ms");
try
{
Thread.sleep(5000); //check every 5 seconds
}
catch (InterruptedException e)
{
Log.d(TAG, "Waiter interrupted!");
}
if(idle > period)
{
idle=0;
//do something here - e.g. call popup or so
}
}
while(!stop);
Log.d(TAG, "Finishing Waiter thread");
}
public synchronized void touch()
{
lastUsed=System.currentTimeMillis();
}
public synchronized void forceInterrupt()
{
this.interrupt();
}
//soft stopping of thread
public synchronized void stop()
{
stop=true;
}
public synchronized void setPeriod(long period)
{
this.period=period;
}
}
【讨论】:
所以我会亲自使用AlarmService。您可以指定一个 PendingIntent 来启动一个显示对话框的活动。在任何应该重新启动计时器的事件之后,您只需取消pendingIntent 并重新注册它。
【讨论】:
我认为CountDownTimer 是最好的方法。
public class IdleCountDownTimer extends CountDownTimer {
public IdleCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
@Override
public void onFinish() {
//Time lapsed
Toast.makeText(getApplicationContext(),"The text you want to display",Toast.LENGTH_LONG)
}
@Override
public void onTick(long millisUntilFinished) {
}
}
现在声明全局对象
IdleCountDownTimer idleCountDownTimer;
现在初始化并开始倒计时。
@Override
public void onCreate()
{
super.onCreate();
idleCountDownTimer = new IdleCountDownTimer(seconds * 60 * 1000, interval_in_seconds * 60 * 1000);
idleCountDownTimer.start();
}
现在调用取消并在您想重置倒计时时开始。
例如 1:用于所有按键、触摸或轨迹球事件
@Override
public void onUserInteraction(){
super.onUserInteraction();
//Reset the count down
idleCountDownTimer.cancel();
idleCountDownTimer.start();
}
例如 2:仅适用于触摸事件
@Override
public boolean onTouchEvent(MotionEvent event) {
//Reset the count down
idleCountDownTimer.cancel();
idleCountDownTimer.start();
// Let the event flow
return false;
}
【讨论】: