Change length of Countdowntimer - java

I want to change the length of my Countdowntimer when it finishs. So I got a Random Number which changes everytime.
standby_time = 15000
standby_counter = new CountDownTimer(standby_time,1000) {
#Override
public void onTick(long millisUntilFinished) {
++standby_zaehler;
}
#Override
public void onFinish() {
...
standby_zaehler = 0;
rndm_groesse = 60000;
random_zahl = r.nextInt(rndm_groesse);
standby_time = random_zahl;
standby_counter.start();
}
};
Where is my fault ? The time is not changing and takes the first value (15sec)

The countdown timers time isnt ment to be changed. You can recreate the timer to alter the time but because you are looking to start it again inside the onFinish() method it would be wise to use a different implementation better suited for this task. The java.util.Timer class does this well.
private Timer timer = new Timer();
private int standby_zaehler = 0;
private Random r = new Random();
public void scheduleNextTimer() {
// reset our countdown
standby_zaehler = 0;
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// 1 second passed, remove it to the countdown
--standby_zaehler;
// we are finished counting down. get a new max seconds
if(standby_zaehler < 0) {
standby_zaehler = r.nextInt(60);
}
}
}, 1000, 1000);
}
As you can see we dont even need to create a new timer, just reset the number and begin again.

Related

How to loop through timer class for delayed time?

I want run timer for about 30000 ms and up to 8 or more times each so here is my loop but it runs all timers at once after 30000ms
public void repeatTimerTask() {
repeat = 8; // need to run 30 sec timer for 8 times but one after one
startTimer(30000); // firsat timer for 30 sec
Handler handler = new Handler();
for (int a = 1; a<=repeat; a++) {
final int finalA = a;
handler.postDelayed(new Runnable() {
#Override
public void run() {
startTimer(30000);
}
}, 30000); // delay until to finish first timer for 30 sec
}
}
To run a timer for n seconds you can use CountDownTimer
Declare two varibales globbaly. One for number of times you want to repeat. and one to keep the count of repetaion.
private int NUM_REPEAT = 4;
private int REPEAT_COUNT = 0;
Then call this method wherever you want. One thing to note if you want to run this loop 5 times you have to give number of repeation 4. Cause to satrt this function you have to call it so that will not come in count.
private void startTimer() {
new CountDownTimer(3000, 1000) {
int secondsLeft = 0;
public void onTick(long ms) {
if (Math.round((float) ms / 1000.0f) != secondsLeft) {
secondsLeft = Math.round((float) ms / 1000.0f);
// resend_timer is a textview
resend_timer.setText("remaining time is "+secondsLeft);
;
}
}
public void onFinish() {
Log.d(TAG, "timer finished "+REPEAT_COUNT);
if (REPEAT_COUNT <= NUM_REPEAT) {
startTimer();
REPEAT_COUNT++;
}
}
}.start();
}
Please try the below code, and call 'startTimer' method where you first want to start your timer :
private int startTimerCount = 1, repeat = 8;
private void startTimer(){
// if startTimerCount is less than 8 than the handle will be created
if(startTimerCount <= repeat){
// this will create a handler which invokes startTimer method after 30 seconds
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
startTimer();
}
}, 30000);
// do what you want
Toast.makeText(this, "startTimer " + startTimerCount, Toast.LENGTH_SHORT).show();
}
startTimerCount++;
}

Using a variable inside Timer

I'm working on a program that has a prints time only when a function is called. I'm using timer for the continuous adding of seconds.
Timer gameTimer = new Timer ();
TimerTask time = new TimerTask() {
int sec = 0;
public void run()
{
sec++;
}
};
gameTimer.scheduleAtFixedRate(time, 1000, 1000);
However, I cannot use the variable sec outside the run() so I can print it. I tried to place sec outside TimerTask but of course sec++ would not work. Any help? Thanks!
Since only final variables accessible in anonymous class, but with this below hack you can achieve what you want.
final int [] result = new int[1]; // Create a final array
TimerTask time = new TimerTask() {
int sec = 0;
public void run()
{
sec++;
result[0] = sec;
}
};
// Now Print whenver you want it
System.out.println(result[0]);
This way you are not reassigning the array to a new object just changing the content inside it
Just make your own interface extending the original interface.
https://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html
interface CustomTimerTask extends TimerTask {
public int getTicks();
}
CustomTimerTask time = new CustomTimerTask () {
int sec = 0;
#Override
public void run()
{
sec++;
}
#Override
public synchronized int getTicks() {
return sec;
}
};
System.out.println("The time passed is: " + time.getTicks());
Just make sure you make it synchronized because you're working with two threads now.

Handler.postDelayed causes lag

I created an application that can call using our SIP server. Now I want to do is to show the user how long his call has been on going. My script is actually working but I noticed that the longer the call, the laggy my app becomes. Here's the snippet of my code
Handler h = new Handler(Looper.getMainLooper());
_isOnCall = true;
long time = 0;
int x = 0;
while(_isOnCall) {
if (_isOnCall){
final int counter = 1 + x;
time += 1000;
h.postDelayed(new Runnable() {
#Override
public void run() {
(TargetDetailsActivity.this).runOnUiThread(new Runnable() {
#Override
public void run() {
final int seconds = counter % 60;
final int minutes = (counter % 3600) / 60;
final int hours = counter / 3600;
callcounter.post(new Runnable() {
#Override
public void run() {
callcounter.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
}
});
}
});
}
}, time);
x++;
}else{
break;
}
}
Basically what the code does is just to count the seconds/minutes/hour he's been on the phone. When he hangs up, I call the code below:
_isOnCall = false;
h.removeCallbacksAndMessages(null);
I'm not sure what causes the lag. Help! Thanks.
UPDATE
I was able to make this working by utilizing galvan's suggestion using Timer. Here's my code for future reference:
private Timer myTimer;
private int counter_time=0;
public void onCallEstablished() {
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
#Override
public void run() {
TimerMethod();
}
}, 0, 1000);
}
private void TimerMethod()
{
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
counter_time++;
int seconds = counter_time % 60;
int minutes = (counter_time % 3600) / 60;
int hours = counter_time / 3600;
callcounter.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
}
};
public void releaseCall(){
if(myTimer != null){
myTimer.cancel();
myTimer.purge();
counter_time = 0;
}
}
It looks like every Runnable saves a reference to his parent object, a nested Runnable in this case. Try to take an heap snapshot for detecting a memory issues to see if this is the case here.
You can also make a repeat task with time interval, and stop the loop when the call ends.
Timer timer = new Timer();
TimerTask myTask = new TimerTask() {
#Override
public void run() {
// whatever you need to do every 2 seconds
}
};
timer.scheduleAtFixedRate(myTask,
firstTime,
period);
for more info about timer you can take a look at the docs

Postponing timer schedule java

At TIME = 0, a user calls a method that sets a flag after 10 seconds. (at TIME = 10)
If the user calls the method again at TIME = 2 the flag should NOT be set at TIME = 10, but instead at TIME = 12:
boolean myFlag; // initializes to false
private Timer timer;
public void setFlag() {
// remove old timer if there was one
if (timer != null) { timer.cancel(); timer = null; }
// set the new timer
timer = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() { myFlag = true; }
};
timer.schedule(tt, 10000);
}
Are there any cleaner ways to implement this "updated-schedule-time" model? Examples are appreciated.
I would have simply kept it the same but made little changes.
Declare the variables always as variables should be declared and initialized near they are first used.
public void setFlag() {
Timer timer;
timer = new Timer();
// remove old timer if there was one
if (timer != null) { timer.cancel(); }
// set the new timer
TimerTask tt = new TimerTask() {
#Override
public void run() { setFlag(); }
};
timer.schedule(tt, 10000);
}

Associating timer with tables

I am new to timer's and don't know much about them .My problem is i am creating 2 tables dynamically, and when ever a table is create a timer for 10 mins is assigned to it. I.e. the user has to fill that table in 10 mins else the table will be destroyed. I tried a making a small demo in which i print stuff
The code is :
final Timer mytimers = new Timer();
Timer mytimers1 = new Timer();
mytimers1 = new Timer();
final long delay1 = 5*1000;
// mytimers = new Timer();
mytimers.schedule(new TimerTask() {
Long current1 = System.currentTimeMillis();
long check = current1;
#Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println(current);
System.out.println("\n");
if((current1 + delay1)<current)
{
System.out.println("mytimmer is about to stop");
mytimers.cancel();
}
}
}, 100, 1000);
mytimers1.schedule(new TimerTask() {
#Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println("in" + current);
}
}, delay1, 1000);
}
but when i tried implementing this int he final project it does not work as i have to make any variable inside the run a final , thus its value can not to be changed !!!
Please let what should i do !!Thank you
i have to make any variable inside the run a final , thus its value can not to be changed!
Either turn these variables into member variables or encapsulate these values in a proper class, instantiate the class and give a reference to that object to the timer task.
Even though the reference is final, the timer task will still be able to do things such as myTableController.destroyTable().
do it like this :
class YourClass{
Timer mytimers = new Timer();
Timer mytimers1 = new Timer();
long delay1 = 5*1000;
mytimers.schedule(new TimerTask() {
Long current1 = System.currentTimeMillis();
long check = current1;
#Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println(current);
System.out.println("\n");
if((current1 + delay1)<current) {
System.out.println("mytimmer is about to stop");
mytimers.cancel();
}
}
}, 100, 1000);
mytimers1.schedule(new TimerTask() {
#Override
public void run() {
Long current = System.currentTimeMillis();
System.out.println("in" + current);
}
}, delay1, 1000);
}
in your case you have created anonymous 'concrete' class ie TimerTask, and you are trying to access variables which are not in its scope.
So, if the variables you are trying to access are local(method) variables then they should be declared final or the other way around is to declare those variables as instant(member) variables that what i have done above.

Categories