I want to put delay of around 60 seconds in my code. I have used the following code, to put some delay; but it doesn't behave as expected.
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//Calling my function after 15 seconds delay.
}
}, 15000);
p.s. : I don't want to use Thread.sleep(), as it creates hindrance in normal operation of application.
You can try CountDownTimer.
// You can change millisInFuture and countDownInterval according to your need.
long millisInFuture = 60000;
long countDownInterval = 1000;
new CountDownTimer(millisInFuture, countDownInterval) {
#Override
public void onTick(long l) {
// Method call according to countDownInterval.
// For E.g we are taking 1000 so this method call every 1 second.
}
#Override
public void onFinish() {
// When 60 second completed call this method.
// Do your logic here.
}
}.start();
Actual thing you want to do like this.
long millisInFuture = 60000;
long countDownInterval = 1000;
int counter = 0;
new CountDownTimer(millisInFuture, countDownInterval) {
#Override
public void onTick(long l) {
// Method call according to countDownInterval.
// For E.g we are taking 1000 so this method call every 1 second.
}
#Override
public void onFinish() {
// When 60 second completed call this method.
// Do your logic here.
counter++;
if (counter == 1) {
// Call your 1st function
} else if (counter == 2) {
// Call your 2nd function
} else if (counter == 3) {
// Call your 3rd function
} else if (counter == 4) {
// Call your 4th function
} else if (counter == 5) {
// Call your 5th function
}
if (counter < 5) {
start();
}
}
}.start();
Related
I am trying to use a runnable to count down from 30s to 0, then run a method, then restart. I cannot seem to get this working right. Seems like a very convoluted solution for a simple task...
tvHeatCD is a TextView that should update every sec to show "5s" if 5 seconds remain etc
reduceHeat() is the method that should run every 30 seconds (matching conditions shown)
stopHeatTimer() is just calling handler.removeCallbacks(..) and heatTimerRunning = false
public void checkHeatTimer() {
RealmResults<Heat> heatList = realm.where(Heat.class).equalTo("theheat","theheat").findAll();
ht = heatList.get(0);
if(ht.getHeat() !=0) {
if(!heatTimerRunning) {
final int[] countdown = {30};
tvHeatCD.setVisibility(View.VISIBLE);
heatRunnable = new Runnable() {
#Override
public void run() {
heatTimerRunning = true;
if (!realm.isClosed()) {
countdown[0]--;
if(countdown[0] == 0) {
if (ht.getHeat() != 0) {
Crashlytics.setInt("heat", ht.getHeat());
reduceHeat("normal",20);
stopHeatTimer();
checkHeatTimer();
} else {
Crashlytics.setInt("heat", 0);
tvHeatCD.setVisibility(View.GONE);
stopHeatTimer();
}
}
tvHeatCD.setText(countdown[0] + "s");
heatHandler.postDelayed(heatRunnable, 1000);
} else if (realm.isClosed()) {
recreate();
}
}
};
heatHandler.postDelayed(heatRunnable, 30000);
}
} else {
tvHeatCD.setVisibility(View.GONE);
}
}
Appreciate any help...thank you!
I'm in the middle of a Football Match Timer project. Basically, I'm looking for an implementation of a timer which starts after pushing a "START 1st half" button, counts to 45 minutes, than pauses and we are able to start it again pushing "START 2nd half"(it would be the same button, but its text would be changed through the whole match). Then it would count from 45 minutes to 90 minutes.
I've been trying to accomplish this using Handler(), Runnable() and onClickListener(), but it doesn't work at all for me :( Would you give me some suggestions about how to tackle this?
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
showTimeRemaining();
timerHandler.postDelayed(this, 500);
}
};
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Button b = (Button) v;
startButton(v);
if (b.getText().equals("Mecz trwa")) {
timerHandler.removeCallbacks(timerRunnable);
b.setEnabled(true);
} else {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
b.setText("Mecz trwa");
b.setEnabled(false);
}
}
});
public void showTimeRemaining() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
timerTextView = (TextView) findViewById(R.id.time);
timerTextView.setText(String.format("%d:%02d", minutes, seconds));
}
Here are some of my suggestions.
First, encapsulate your Handler into a class called Timer. This way it's easier to manipulate your timers. Here is my version:
import android.os.Handler;
public class Timer {
private Handler handler;
private boolean paused;
private int interval;
private Runnable task = new Runnable () {
#Override
public void run() {
if (!paused) {
runnable.run ();
Timer.this.handler.postDelayed (this, interval);
}
}
};
private Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startTimer () {
paused = false;
handler.postDelayed (task, interval);
}
public void stopTimer () {
paused = true;
}
public Timer (Runnable runnable, int interval, boolean started) {
handler = new Handler ();
this.runnable = runnable;
this.interval = interval;
if (started)
startTimer ();
}
}
Secondly, don't use System.currenTimeMillis. Use something more manipulatable. Create a variable of your own that stores how many seconds are left:
private int secondsLeft = 60 * 45;
You decrement this variable every second, until it reaches zero. Then, you stop the timer, change the button's text or whatever. This logic should be put into the Runnable used for the handler.
I would suggest to try using of CountDownTimer.
Refer here for documentation and usage:
https://developer.android.com/reference/android/os/CountDownTimer.html
I've made a custom stop watch which showing hours:minuted:seconds.Controls are given by START and STOP buttons.But, there is a problem when stopping the stopwatch.It didn't stop when the STOP button is clicked. Anybody please suggest me the right solution.
package com.example.mystopwatch;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class StopwatchActivity extends Activity {
private TextView textViewTimer;
private Button BtnStart,BtnStop;
private Handler mHandler = new Handler();
private long startTime;
private long elapsedTime;
private final int REFRESH_RATE = 100;
private String hours,minutes,seconds,milliseconds;
private long secs,mins,hrs,msecs;
private boolean stopped = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stopwatch);
BtnStart=(Button)findViewById(R.id.startbtn);
BtnStop=(Button)findViewById(R.id.stopbtn);
BtnStart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Runnable startTimer1 = new Runnable()
{
public void run()
{
elapsedTime = System.currentTimeMillis() - startTime; updateTimer(elapsedTime);
mHandler.postDelayed(this,REFRESH_RATE);
}
};
if(stopped)
{
startTime = System.currentTimeMillis() - elapsedTime;
}
else
{
startTime = System.currentTimeMillis();
}
mHandler.removeCallbacks(startTimer1);
mHandler.postDelayed(startTimer1, 0);
}
});
BtnStop.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Runnable startTimer2 = new Runnable()
{
public void run()
{
elapsedTime = System.currentTimeMillis() - startTime; updateTimer(elapsedTime);
mHandler.postDelayed(this,REFRESH_RATE);
}
};
mHandler.removeCallbacks(startTimer2);
stopped = true;
}
});
}
private void updateTimer(long time) {
// TODO Auto-generated method stub
secs = (long)(time/1000);
mins = (long)((time/1000)/60);
hrs = (long)(((time/1000)/60)/60);
secs = secs % 60;
seconds=String.valueOf(secs);
if(secs == 0)
{
seconds = "00";
}
if(secs <10 && secs > 0)
{
seconds = "0"+seconds;
}
mins = mins % 60;
minutes=String.valueOf(mins);
if(mins == 0){ minutes = "00";
}
if(mins <10 && mins > 0)
{
minutes = "0"+minutes;
}
hours=String.valueOf(hrs);
if(hrs == 0)
{
hours = "00";
}
if(hrs <10 && hrs > 0)
{
hours = "0"+hours;
}
milliseconds = String.valueOf((long)time);
if(milliseconds.length()==2)
{
milliseconds = "0"+milliseconds;
}
if(milliseconds.length()<=1)
{ milliseconds = "00";
}
milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-2);
((TextView)findViewById(R.id.timertxt)).setText(hours + ":" + minutes + ":" + seconds);
}
}
Most of the code in your BtnStop.setOnClickListener is actually useless. You define a Runnable called startTimer2, but for what purpose? You never use that Runnable except in the call to mHandler.removeCallbacks(startTimer2);. That will remove any calls that were made to it before, but since you never made any, this does not do anything.
The only thing your method does when you click the stop button is to set the boolean flag stopped to true. But there is no periodic process checking that flag. The only time you check the flag is when the START button is pressed.
As a side note, your use of REFRESH_RATE is confusing. Setting a higher number will actually result in a lower refresh rate since postDelayed takes a duration. Consider renaming the variable or adding a division.
It can not stop since you don't check boolean stopped in your run method. Move it inside :
public void run() {
elapsedTime = System.currentTimeMillis() - startTime;
updateTimer(elapsedTime);
if(!stopped) {
mHandler.postDelayed(this, REFRESH_RATE);
}
}
and also consider declaring stopped as volatile as per suggestion in the comments.
there is whole task to start and stop , stopwatch just call :-- handler.sendEmptyMessage(MSG_STOP_TIMER); to stop stopwatch
Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_START_TIMER:
timer.start(); //start timer
handler.sendEmptyMessage(MSG_UPDATE_TIMER);
break;
case MSG_UPDATE_TIMER:
//timerText.setText(String.format("%1$tM:%1$tS",timer.getElapsedTimeMin(),timer.getElapsedTimeSecs()));
if ( timer.getElapsedTimeSecs() < 10)
{
if(timer.getElapsedTimeMin()<10){
timerText.setText("0" + timer.getElapsedTimeMin() + ":0" + timer.getElapsedTimeSecs());
}else{
timerText.setText("" + timer.getElapsedTimeMin() + ":0" + timer.getElapsedTimeSecs());
}
}
else{
if(timer.getElapsedTimeMin()<10){
timerText.setText("0" + timer.getElapsedTimeMin() + ":" + timer.getElapsedTimeSecs());
}else{
timerText.setText(timer.getElapsedTimeMin()+":"+ timer.getElapsedTimeSecs());
}
}
handler.sendEmptyMessageDelayed(MSG_UPDATE_TIMER,REFRESH_RATE); //text view is updated every second,
break; //though the timer is still running
case MSG_STOP_TIMER:
handler.removeMessages(MSG_UPDATE_TIMER); // no more updates.
timer.stop();//stop timer
timerText.setText("0"+timer.getElapsedTimeMin()+":0"+ timer.getElapsedTimeSecs());
break;
default:
break;
}
}
};
as seen in Sam's post on
here, I am unsure what method to use to start the countdown timer "AccurateCountDownTimer".
It will be called from a button (onClick) which is easily set up later.
And the Time remaining will be displayed on a text view.
Here is my code:
public abstract class AccurateCountDownTimer {
public AccurateCountDownTimer(long millisInFuture, long countDownInterval) {
long seconds = (millisInFuture / 1000);
mMillisInFuture = millisInFuture;
mCountdownInterval = countDownInterval;
// ************AccurateCountdownTimer***************
mTickCounter = 0;
// ************AccurateCountdownTimer***************
testTimer.setText(String.format("%02d", seconds / 60) + ":"
+ String.format("%02d", seconds % 60));
}
/**
* Cancel the countdown.
*/
public final void cancel() {
mHandler.removeMessages(MSG);
}
/**
* Start the countdown.
*/
public synchronized final AccurateCountDownTimer start() {
if (mMillisInFuture <= 0) {
onFinish();
return this;
}
mNextTime = SystemClock.uptimeMillis();
mStopTimeInFuture = mNextTime + mMillisInFuture;
mNextTime += mCountdownInterval;
mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG), mNextTime);
return this;
}
/**
* Callback fired on regular interval.
*
* #param millisUntilFinished
* The amount of time until finished.
*/
public abstract void onTick(long millisUntilFinished);{
}
/**
* Callback fired when the time is up.
*/
public abstract void onFinish();
private static final int MSG = 1;
// handles counting down
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
synchronized (AccurateCountDownTimer.this) {
final long millisLeft = mStopTimeInFuture - SystemClock.uptimeMillis();
if (millisLeft <= 0) {
onFinish();
} else {
onTick(millisLeft);
// Calculate next tick by adding the countdown interval from the original start time
// If user's onTick() took too long, skip the intervals that were already missed
long currentTime = SystemClock.uptimeMillis();
do {
mNextTime += mCountdownInterval;
} while (currentTime > mNextTime);
// Make sure this interval doesn't exceed the stop time
if(mNextTime < mStopTimeInFuture)
sendMessageAtTime(obtainMessage(MSG), mNextTime);
else
sendMessageAtTime(obtainMessage(MSG), mStopTimeInFuture);
}
}
}
};
}
I am not sure if i understand your question... Do you ask how to use this class? I think it will be enough to start timer like this:
new AccurateCountDownTimer(millisInFuture, countDownInterval).start();
Edit: And also you can have callbacks like explained in source code:
new AccurateCountDownTimer(millisInFuture, countDownInterval) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
I'm trying to make a countdown timer starting at 10 minutes, similair to a basketball scoreboard: 10:00 to 00:00. How would I do that? This is my code:
private TextView Timer;
Handler handler = new Handler();
private int length = 120000;
private int decision = 0;
MyCount counter;
public String formatTime(long millis) {
String output = "00:00";
long seconds = millis / 1000;
long minutes = seconds / 60;
seconds = seconds % 60;
minutes = minutes % 60;
String sec = String.valueOf(seconds);
String min = String.valueOf(minutes);
if (seconds < 10)
sec = "0" + seconds;
if (minutes < 10)
min= "0" + minutes;
output = min + " : " + sec;
return output;
}//formatTime
#Override
public void onCreate(Bundle cute) {
super.onCreate(cute);
counter = new MyCount(length, 1000);
updateTime();
handler.removeCallbacks(updateTimeTask);
handler.postDelayed(updateTimeTask, 1000);
}//end of cuteness
private Runnable updateTimeTask = new Runnable() {
public void run() {
updateTime();
handler.postDelayed(this, 1000);
}
};
private void updateTime() {
switch (decision) {
case 0:
startTime = 0L;
counter.start();
decision=1;
break;
case 1:
counter.onPause();
decision=0;
break;
}
}//updateTime
class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}//MyCount
public void onPause() {
//do stuff later
onPause();
}//finish
public void onTick(long millisUntilFinished) {
Timer.setText("" + formatTime(millisUntilFinished));
}//on tick
#Override
public void onFinish() {
onStop();
}//finish
}//class MyCount
Any help would be appreciated. thanks!
This does not have to be too hard. You've already created your functionality for writing your time in letters, now you need to count down. Starting a timer is easy, just do this in your start button event handler (or whatever you choose to use) (modified example from the android developer reference:
// New timer for 10 minutes, starts after initialization
new MyCount(600000, 1000)
{
// Updates the text on your "scoreboard" every second
public void onTick(long millisUntilFinished)
{
Timer.setText("Time remaining: " + formatTime(millisUntilFinished));
}
public void onFinish()
{
mTextField.setText("done!");
}
}.start();
And that's all you need! You can skip your UpdateTime function and your updateTimeTask. Just replace all this on your onCreate method
counter = new MyCount(length, 1000);
updateTime();
handler.removeCallbacks(updateTimeTask);
handler.postDelayed(updateTimeTask, 1000);
With my code. Or modify it as you please!
why don't you just create 3 textviews so that it will be easier for you to code?
one for the minutes.
one for the colon.
one for the seconds.
then use the code he's using.
hope I helped.
The way i think of making a count down is just saving at the beginning the (current time + 10 minutes) aside and then just subtract it from current time every second in your handler and display the result in the desired format..