【发布时间】:2011-04-29 08:43:23
【问题描述】:
我开发了一些实现计时器的代码 - 它每秒滴答一次,并且在 x 秒不触摸显示屏后启动“空闲”活动。 但是,这需要为大约 8 个活动实现...我可以将相关代码复制并粘贴到每个活动,但这不是一个优雅的解决方案。
所以,我开始创建自定义活动“TimedActivity”来扩展 Activity。然后我需要实现的其他活动可以实现“TimedActivity”。
但是,我的 TimedActivity 如何检测 onTouch 事件?
这是我目前所拥有的:
public class TimedActivity extends Activity implements OnTouchListener
{
private LinearLayout mLinearLayoutMain;//intended to be the root node in the XML
private Timer mTimerSeconds;
private int mIntIdleSeconds;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//NO setContentView()
mIntIdleSeconds=0;
mTimerSeconds = new Timer();
mTimerSeconds.schedule(new TimerTask()
{
@Override
public void run()
{
timerSecondsCounter();
}
}, 0, 1000);
//the whole screen should become sensitive to touch
//HOWEVER, there's no View established
mLinearLayoutMain = (LinearLayout) findViewById(R.id.layout_main);
//mLinearLayoutMain remains null, so next line excepts
mLinearLayoutMain.setOnTouchListener(this);
}
@Override
protected void onDestroy()
{
if (mTimerSeconds != null)
{
mTimerSeconds.cancel();
}
super.onDestroy();
}
public boolean onTouch(View v, MotionEvent event)
{
mIntIdleSeconds=0;
return false;//do not consume
}
private void timerSecondsCounter()
{
mIntIdleSeconds++;
if (mIntIdleSeconds == Constants.MAX_IDLE_TIME_SECONDS)
{
final Intent intent = new Intent(this, what.ever.com.Idle.class);
startActivity(intent);
}
}
}
使用 this 的后续活动将使用:
public class ActivitySelect extends TimedActivity
{
}
视图的 xml 将是:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/layout_main">
<!-- MORE STUFF --->
</LinearLayout>
我觉得我已经很接近了,但是我需要做些什么才能让它发挥作用?
编辑: 这就是我最终实施的...
public class TimedActivity extends Activity
{
//member variables
private Timer mTimerSeconds;
private int mIntIdleSeconds;
private boolean mBoolInitialized=false;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy()
{
if (mTimerSeconds != null)
{
mTimerSeconds.cancel();
}
super.onDestroy();
}
public void onTouch()
{
mIntIdleSeconds=0;
}
/** start the idle timer */
public void startIdleTimer()
{
if (mBoolInitialized == false)
{
mBoolInitialized = true;
//initialize idle counter
mIntIdleSeconds=0;
//create timer to tick every second
mTimerSeconds = new Timer();
mTimerSeconds.schedule(new TimerTask()
{
@Override
public void run()
{
timerSecondsCounter();
}
}, 0, 1000);
}
}
/** called every second to count idle time and to update clock on Welcome screen */
private void timerSecondsCounter()
{
mIntIdleSeconds++;
if (mIntIdleSeconds == Constants.MAX_IDLE_TIME_SECONDS)
{
//idle time long enough to launch standby activity
final Intent intent = new Intent(this, what.ever.com.Idle.class);
startActivity(intent);
}
}
}
要使用此 ActivityTimed,请在您启动的 Activity 中执行以下操作:
public class ActivitySelect extends TimedActivity implements OnTouchListener
{
//UI references
private LinearLayout mLinearLayout;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);//triggers TimedActivity::onCreate()
setContentView(R.layout.select);
//get references to all of your widgets
mLinearLayout = (LinearLayout) findViewById(R.id.select_linearlayout_main);
//set your widgets as touchable
mLinearLayout.setOnTouchListener(this);
//start the idle timer
super.startIdleTimer();
}
@Override
protected void onDestroy()
{
//this is very important here ;-)
super.onDestroy();
}
public boolean onTouch(View v, MotionEvent event)
{
final int actionPerformed = event.getAction();
//reset idle timer
// put this here so that the touching of empty space is captured too
// it seems that LinearLayout doesn't trigger a MotionEvent.ACTION_UP or MotionEvent.ACTION_MOVE
if (actionPerformed == MotionEvent.ACTION_DOWN)
{
super.onTouch();
}
return false;//do not consume event!
}
}
【问题讨论】:
-
这个超时是为了使某种会话过期,还是将用户发送到登录屏幕?如果是我也遇到过同样的问题,有不同的解决方案。
-
是的,一旦发生超时,就会自动启动不同的活动 - 即登录屏幕、屏幕保护程序等......一些空闲屏幕
-
然后你可以通过使用默认属性来避免这种方法:finishOnTaskLaunch on all but Login (登录活动无法完成,必须在堆栈上。你还可以检测屏幕是否关闭,以及立即发送到登录屏幕。
-
NeTeInStEiN,如果你有时间,你能用代码 sn-ps 演示你的解决方案吗?我已经搜索了一段时间,很多人都想为活动实现某种空闲/超时机制——看看你的解决方案会很有帮助。
标签: android