Count up timer on Android? - java

I've been looking for a way to create a timer that counts up in the format of mm:ss:SS and cannot for the life of me find a way of doing it. I had a timer running through a Handler and a Runnable but the timing was off and it took around 2.5 seconds to do a "second". I'll also need this timer be able to countdown too!
Can anyone give me any resources or code snippets to research on this as it is a big part of the app I'm coding.
Here's a bit of the code that I was using
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
#Override
public void run() {
/* do what you need to do */
testMethod();
/* and here comes the "trick" */
handler.postDelayed(this, 10);
}
};
public void testMethod()
{
// Log.d("Testing", "Test");
final TextView timeLabel = (TextView)findViewById(R.id.timeString);
count++;
seconds = (int)(count / 100);
final String str = ""+count;
runOnUiThread(new Runnable() {
public void run() {
timeLabel.setText("" + seconds);
// Log.d("Time", "" + count);
}
});
}
Ta!

Make small custom class by extending CountDownTimer class and then add integer or long type and then increment it, since each tick is 1 second (integer) in this case
public class TimeCounter extends CountDownTimer {
// this is my seconds up counter
int countUpTimer;
public TimeCounter(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
countUpTimer=0;
}
#Override
public void onTick(long l) {
//since each tick interval is one second
// just add 1 to this each time
myTextView.setText("Seconds:"+countUpTimer);
countUpTimer = countUpTimer+1;
}
#Override
public void onFinish() {
//reset counter to 0 if you want
countUpTimer=0;
}
}
TimeCounter timer = new TimeCounter(whenToStopInSeconds*1000, 1000);
This should get you started, in your case use long instead integer
countUpTimer = countUpTimer+1000 countUpTimer type and do time parsing as suits you

Rather than using the Handler, I'd recommend using the java.util.Timer and the java.util.TimerTask APIs. Use the Timer's void scheduleAtFixedRate() method which basically executes tasks after a fixed interval of time. The Handler's method most likely uses a fixed-delay execution.
Timer's Documentation
TimerTask's Documentation

Related

Call method after delay

I've crated Log in screen, and if user mistake 3 times i want to show timer of 2 min. I want that timer to be visually shown on the screen. I'll try this code and it's work, but I don't know how to display timer on screen.
Handler handler = new Handler();
long waitingTime = 2 * 60 * 1000; // 2 min
handler.postDelayed(new Runnable() {
#Override
public void run()
{
//Do something after 2 min
}
}, waitingTime);
You need to have Handler called every second and update the UI during every pass. When you reach 2 mins you can cancel the handler.
Code should be like this:
final Handler handler = new Handler();
//class variable
count = 0;
handler.post(new Runnable() {
#Override
public void run() {
updateCounter(count++);
if(count < 120) {
handler.postDelayed(this, 1000);
}
}
});
And function to update counter:
private void updateCounter(final int count) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// you have the seconds passed
// do what ever you want
}
});
}
you need use runOnUiThread(Runnable action)

Making a program run for 5 minutes

So I wanted to try out something for a bit with the Timer and TimerTask classes.
I was able to get a line of code to execute after 30 seconds elapsed.
What I've been trying to do now is to get this line of code to execute for 5 minuets.
This is what I originally tried
public static void main(String[] args)
{
for ( int i = 0; i <= 10; i ++ )
{
Timer timer = new Timer();
timer.schedule( new TimerTask()
{
public void run()
{
System.out.println("30 Seconds Later");
}
}, 30000
);
}
}
I used the number 10 in the for loop to see if the timer.schedule would wait for another 30 seconds during the next iteration of the loop.
Any idea how I should go about this? I tried using the schedule method with a parameter passed in for period, but that only made it re-execute and it never stopped.
Java has provided a rich set of APIs in java.util.concurrent package to achieve such tasks. One of these APIs is ScheduledExecutorService. For example consider the code given below: This code will execute the Runnable task after every 30 seconds for upto 5 minutes:
import java.util.concurrent.*;
class Scheduler
{
private final ScheduledExecutorService service;
private final long period = 30;//Repeat interval
public Scheduler()
{
service = Executors.newScheduledThreadPool(1);
}
public void startScheduler(Runnable runnable)
{
final ScheduledFuture<?> handler = service.scheduleAtFixedRate(runnable,0,period,TimeUnit.SECONDS);//Will cause the task to execute after every 30 seconds
Runnable cancel = new Runnable()
{
#Override
public void run()
{
handler.cancel(true);
System.out.println("5 minutes over...Task is cancelled : "+handler.isCancelled());
}
};
service.schedule(cancel,5,TimeUnit.MINUTES);//Cancels the task after 5 minutes
}
public static void main(String st[])
{
Runnable task = new Runnable()//The task that you want to run
{
#Override
public void run()
{
System.out.println("I am a task");
}
};
Scheduler sc = new Scheduler();
sc.startScheduler(task);
}
}
The issue you're running into is that the scheduled Timer runs on a different thread - that is, the next iteration of your for loop starts running immediately after scheduling, not 30 seconds later. It looks like your code starts ten timers all at once, which means they should all print (roughly) 30 seconds later, all at once.
You were on the right track when you tried using the recurring version of schedule (with the third parameter). As you noted, this isn't quite what you want because it runs indefinitely. However, Timer does have a cancel method to prevent subsequent executions.
So, you should try something like:
final Timer timer = new Timer();
// Note that timer has been declared final, to allow use in anon. class below
timer.schedule( new TimerTask()
{
private int i = 10;
public void run()
{
System.out.println("30 Seconds Later");
if (--i < 1) timer.cancel(); // Count down ten times, then cancel
}
}, 30000, 30000 //Note the second argument for repetition
);
here's a workaround I'm ashamed of presenting:
package test;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class FiveMinutes {
private static int count = 0;
// main method just to add example
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
System.out.println("Count is: " + count);
if (count == 1) {
System.err.println("... quitting");
System.exit(0);
}
count++;
}
},
// starting now
new Date(),
// 5 minutes
300000l
);
}
}
Also please note that the application might not run exactly 5 minutes - see documentation for TimerTask.
Your solution is pretty close to working, you just have to multiply the delay by the counter (in your case, i):
public static void main(String[] args)
{
for (int i = 1; i <= 10; i++) // start i at 1 for initial delay
{
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run()
{
System.out.println("30 Seconds Later");
}
}, 30000 * i); // 5 second intervals
}
}
I don't know if this solution has problems with the garbage collector or not, but I throw it in here anyways. Maybe someone clears that out, and I learn something as well. Basically a timer sets a new timer if there is time left, and it should stop after 5 minutes.
Main.java:
public class Main {
public static void main(String[] args) {
MyTimer myTimer = new MyTimer(300000,30000);
myTimer.startTimer();
}
}
MyTimer.java:
import java.util.Timer;
import java.util.TimerTask;
public class MyTimer {
private int totalRunningTime;
private int currentTime = 0;
private int intervalTime;
private Timer timer = new Timer();
public MyTimer(int totalRunningTime, int intervalTime) {
this.totalRunningTime = totalRunningTime;
this.intervalTime = intervalTime;
}
public void startTimer() {
startTimer(intervalTime);
}
private void startTimer(int time) {
timer.schedule(new TimerTask() {
public void run() {
if (currentTime <= totalRunningTime - intervalTime) {
printTimeSinceLast(intervalTime / 1000);
currentTime += intervalTime;
startTimer(intervalTime);
} else if (currentTime < totalRunningTime) {
int newRestIntervalTime = totalRunningTime - currentTime;
printTimeSinceLast(newRestIntervalTime / 1000);
currentTime += newRestIntervalTime;
startTimer(newRestIntervalTime);
}
}
}, time);
}
private void printTimeSinceLast(int timeSinceLast) {
System.out.println(timeSinceLast + " seconds later.");
}
}

how to update the textview variable for every 5 seconds [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Updating TextView every N seconds?
Here, I want to update the Hr value in the textview once it is calculated for every iteration, but with a delay of 2 seconds each time. I dont know how to do it. What i get now in the textview is the last value of the iteration. I want all the values to be displayed at a constant delay. anyone help pls.
for(int y=1;y<p.length;y++)
{
if(p[y]!=0)
{
r=p[y]-p[y-1];
double x= r/500;
Hr=(int) (60/x);
Thread.sleep(2000);
settext(string.valueof(Hr));
}
}
public class MainActivity extends Activity{
protected static final long TIME_DELAY = 5000;
//the default update interval for your text, this is in your hand , just run this sample
TextView mTextView;
Handler handler=new Handler();
int count =0;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView=(TextView)findViewById(R.id.textview);
handler.post(updateTextRunnable);
}
Runnable updateTextRunnable=new Runnable(){
public void run() {
count++;
mTextView.setText("getting called " +count);
handler.postDelayed(this, TIME_DELAY);
}
};
}
I hoped this time you will get into the code and run it .
use Handler or TimerTask(with runOnUiThread()) instead of for loop for updating text after every 5 seconds as :
Handler handler=new Handler();
handler.post(runnable);
Runnable runnable=new Runnable(){
#Override
public void run() {
settext(string.valueof(Hr)); //<<< update textveiw here
handler.postDelayed(runnable, 5000);
}
};
you should use timer class....
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
}, 900 * 1000, 900 * 1000);
Above code is for every 15 minutes.change this value and use in your case.....
TimerTask is just what you need.
lets us just hope it helps you sufficiently
import java.awt.Toolkit;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class demo
{
Toolkit toolkit;
Timer timer;
public demo()
{
toolkit = Toolkit.getDefaultToolkit();
timer = new Timer();
timer.schedule(new scheduleDailyTask(), 0, //initial delay
2 * 1000); //subsequent rate
}
class scheduleDailyTask extends TimerTask
{
public void run()
{
System.out.println("this thread runs for every two second");
System.out.println("you can call this thread to start in your activity");
System.out.println("I have used a main method to show demo");
System.out.println("but you should set the text field values here to be updated simultaneouly");
}
}
public static void main(String args[]) {
new demo();
}
}

Android CountDownTimer scoping

Can anyone tell me if this is a safe thing to do? I run a countdown timer (CountDownTimer) and when the timer reaches zero it must start again, counting down for, for example, a longer time. To do this I call
timer = new TableCount(nextTime * 1000, 100);
within the onFinish() method.
It runs without problems, but I'm concerned it may cause a memory leak. Should I rather have the timer fire some kind of notification that it is done? Here are the important bits from the activity code:
public class TableActivity extends Activity {
TableCount timer; // the count down timer
protected int nextTime;
...
// somewhere I call this - user clicked the "start" button
timer = new TableCount(nextTime * 1000, 100);
nextTime += 100; // for example
...
public class TableCount extends CountDownTimer
{
public void onFinish() {
... // check if number of iterations has been reached, else:
// start counting down from the next value
timer = new TableCount(nextTime * 1000, 100);
nextTime += 100; // for example
}
}
You will not leak memory since you are simply changing the reference of your single declaration of TableCount to a new timer which implicitly dereferences the previous object.
Even if you did something bizarre like creating a new timer each run and adding it to an array (for example) you would still not leak. You might eventually run out of memory but that's not the same as leaking since when the activity is finished(), and assuming that you are not holding a static reference somewhere else, then the memory is freed and eligible for garbage collection.
However, why not just reuse the existing timer and use schedule() to run it again?
do not need to initialize timer again....
try this...
int temp=nexttime;
public class TableCount extends CountDownTimer
{
public void onFinish() {
nexttime=temp;
timer.start();
}
}
public class ServiceCount extends CountDownTimer
{
public ServiceCount(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish()
{
count = new ServiceCount((long) (1 * 60 * 1000), 1000); // 1 minute
count.start();
}
#Override
public void onTick(long millisUntilFinished)
{
Log.d("timer", "" + millisUntilFinished / 1000);
}
}
ServiceCount count = new ServiceCount((long) (1 * 60 * 1000), 1000); // 1 minute
count.start();

Blackberry timer not firing TimerTask

I am trying to use a time that updates a label every second (so it shows a countdown) but it only
appears to be "ticking" once and I can't work out what I'm doing wrong!
public class Puzzle extends UiApplication {
public static void main(String[] args) {
Puzzle puzzle = new Puzzle();
puzzle.enterEventDispatcher();
}
public Puzzle() {
pushScreen(new PuzzleScreen());
}
}
class PuzzleScreen extends MainScreen {
LabelField timerLabel;
Timer timer;
public static int COUNT = 0;
public PuzzleScreen() {
//set up puzzle
VerticalFieldManager vfm = new VerticalFieldManager();
add(vfm);
timerLabel = new LabelField();
timerLabel.setText("00:20");
vfm.add(timerLabel);
StartTimer();
}
void StartTimer() {
timer = new Timer();
timer.schedule(new TimerTick(), 1000);
}
private class TimerTick extends TimerTask {
public void run() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
timerLabel.setText((COUNT++) + "");
}
});
}
}
Can anyone see what I am doing wrong..? All that happens is my label get's set to "0" and then doesn't change. I have put a breakpoint on the run in the timer tick class but I don't see it firing!
Bex
You'll need to change your Timer's schedule() call to
timer.schedule(new TimerTick(), 0, 1000);
The way you're calling it right now is saying to run it once after a second delay. This way says to run it now and every second. You probably want to use
timer.scheduleAtFixedRate(new TimerTick(), 0, 1000);
though, because it will make sure that on average your TimerTask is ran every second rather than with a normal schedule() call that says it will try waiting a second then executing, but it could fall behind if something slows it down. If scheduleAtFixedRate() is delayed, it will make multiple calls quicker than on the 1 second delay so it can "catch up." Take a look at http://www.blackberry.com/developers/docs/5.0.0api/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask,%20long,%20long) for a more detailed explanation.

Categories

Resources