儿童活动中的倒数计时器

时间:2018-07-21 07:34:17

标签: android android-activity timer background-process countdowntimer

我制作了一个需要在儿童活动中运行倒数计时器的应用程序。回到主要活动(或按“返回”)时,如何保持计时器运行并跟踪时间?

 play.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
          if(!isRunning){

              timerTextHelper.start();
              isRunning =true;

          }else {
              timerTextHelper.stop();
              long elapsedTime = timerTextHelper.getElapsedTime();
              Log.v("TAG","TIME: "+ elapsedTime/1000);
              isRunning =false;

我尝试使用Runnable

 @Override
    public void run() {
        long millis = System.currentTimeMillis() - startTime;
        int seconds = (int) (millis / 1000);
        int minutes = seconds / 60;
        seconds = seconds % 60;

        textView.setText(String.format("%d:%02d", minutes, seconds));

        if (elapsedTime == -1) {
            handler.postDelayed(this, 500);
        }
    }

    public void start() {
        this.startTime = System.currentTimeMillis();
        this.elapsedTime = -1;
        handler.post(this);
    }

    public void stop() {
        this.elapsedTime = System.currentTimeMillis() - startTime;
        handler.removeCallbacks(this);
    }

    public long getElapsedTime() {
        return elapsedTime;

2 个答案:

答案 0 :(得分:0)

实施以下课程:

public class OtpTimer extends CountDownTimer {
/**
 * @param millisInFuture    The number of millis in the future from the call
 *                          to {@link #start()} until the countdown is done and {@link #onFinish()}
 *                          is called.
 * @param countDownInterval The interval along the way to receive
 *                          {@link #onTick(long)} callbacks.
 */
private  OtpTimer(long millisInFuture, long countDownInterval) {
    super(millisInFuture, countDownInterval);
}
private static OtpTimer otpTimer;
private static TextView otp_text;
private static long sec,min;

/**
 *
 * @param millisInFuture total time of timer
 * @param countDownInterval callback time of {@link #onTick(long)}
 * @param textView instace of textview to show time in text view
 */
public static synchronized void getInstance(long millisInFuture, long countDownInterval, TextView textView)
{
    if(otpTimer==null) {
        otpTimer = new OtpTimer(millisInFuture, countDownInterval);
        otpTimer.start();
    }
    otp_text=textView;
    if(min>=1 && sec>=10)
        otp_text.setText("0"+String.valueOf(min)+":"+String.valueOf(sec));
    else if(min>=1 && sec<=10)
    {
        otp_text.setText("0"+String.valueOf(min)+":"+"0"+String.valueOf(sec));
    }
    else if(sec>=10)
        otp_text.setText("00"+":"+String.valueOf(sec));
    else if(sec==0)
        otp_text.setText("Start again");
    else
        otp_text.setText("00"+":"+"0"+String.valueOf(sec));

}
@Override
public void onTick(long millisUntilFinished) {
    sec=millisUntilFinished/1000;
    min=sec/60;
    sec=sec%60;
    if(min>=1 && sec>=10)
        otp_text.setText("0"+String.valueOf(min)+":"+String.valueOf(sec));
    else if(min>=1 && sec<=10)
    {
        otp_text.setText("0"+String.valueOf(min)+":"+"0"+String.valueOf(sec));
    }
    else if(sec>=10)
        otp_text.setText("00"+":"+String.valueOf(sec));
    else
        otp_text.setText("00"+":"+"0"+String.valueOf(sec));
}

@Override
public void onFinish() {
    sec=0;
    otp_text.setText("Start again");
}
public static void Restart(long millisInFuture, long countDownInterval, TextView textView,Boolean voice,Boolean contact){
    if(otpTimer!=null)
    {
        otpTimer.cancel();
        otpTimer=null;
    }
    getInstance(millisInFuture, countDownInterval,textView,voice,contact);
}

public static void setNull()
{
    if(otpTimer!=null)
    {
        otpTimer.cancel();
        otpTimer=null;
    }
}}

现在要启动计时器,只需在onCreate和onResume中调用以下行:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    OtpTimer.getInstance(30000,1000,m_otp_timer);
}

@Override
protected void onResume() {
    invalidateOptionsMenu();
    super.onResume();
    OtpTimer.getInstance(30000,1000,m_otp_timer);
}

这里有30秒计时器,计数将增加1秒,而m_otp_timer是将显示计数的文本视图。

要重新启动计时器,只需调用:

OtpTimer.Restart(30000, 1000, m_otp_timer);

答案 1 :(得分:0)

创建一个git pull upstream并将其注册到您的清单

broadCastReceiver

该操作用于仅向接收者发送意图

并为您的接收器创建一个类

<receiver
    android:name=".receivers.TimerReceiver">
    <intent-filter>
        <action android:name="YOUR.PACKAGE.NAME.action.RECEIVER_TIMER" />
    </intent-filter>
</receiver>

然后在活动的正文中创建接收者的实例

class TimerReceiver : BroadcastReceiver(val callback:Callback) {
    override fun onReceive(context: Context?, data: Intent?) {
        callback.onNewTime(data.getIntExtra("min",0),data.getIntExtra("sec",0))
    }
    interface Callback {
        fun onNewTime(int min,int sec)
    }
}

然后在活动的TimerReceiver receiver; 中创建对象

onCreate()

然后在您活动的receiver = TimerReceiver(this) 中注册您的接收者

onStart

,然后在您活动的registerReceiver(receiver,IntentFilter("YOUR.PACKAGE.NAME.acrion.RECEIVER_TIMER")) 中取消注册接收者

onStop

最后在您的活动中实施unregisterReceiver(receiver) 方法

TimerReceiver.Callback

因此,当您想更新计时器override fun onNewTime(min:Int,sec:Int){ textView.setText(String.format("%d:%02d", min, sec)); } 并将分钟和秒放入TimeTask时,就可以使用sendBroadCast了。