Countdowntimer onTick method not displaying proper seconds - java

For my code I use a countdown timer, however I add seconds to it as after they get an answer correct, the timer is reset to 5 seconds. The problem with this is that the text that displays the time still has the wrong number, it doesn't repeat digits. For instance if it was a 5 second timer and it goes 5,4,3 then the user gets it right, the time will go 3, 3, 3, 2, 1.
Here is my countdown code
n = 5000;
time = new TextView(this);
time.setTextColor(Color.parseColor("#FFFFFF"));
timer = new CountDownTimer(n, 1000) {
public void onTick(long millisUntilFinished) {
time.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
Intent endIntent = new Intent(MainActivity.this, Endgame.class);
endIntent.putExtra("rounds",round);
MainActivity.this.startActivity(endIntent);
}
}.start();
Then if the user gets the question right - this is the part that restarts it
if(person == false){
picturechanger();
n=5000;
timer.onTick(5000);
}

Try:
if(person == false){
picturechanger();
n=5000; // Not sure why u put n=5000 here..?
if(timer != null)
timer.cancel();
timer.start();
}

Related

How to build Time Speaking clock

I new to Android programming and I want to build Time Speaking clock that will speak the current time in every hour.
Please help me with my code, I want it to say the current time in every hour, but It say it in every second, here is my code.
.........................
.........................................................................................................
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tts = new TextToSpeech(this, this);
time_textView = findViewById(R.id.time_textView);
hour_textView = findViewById(R.id.hour_textView);
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
#Override
public void run() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("h:mm:ss", Locale.getDefault());
String currentTime = simpleDateFormat.format(calendar.getTime());
time_textView.setText(currentTime);
Hour = calendar.getTime().getHours();
Minute = calendar.getTime().getMinutes();
if (Hour == 1 && Minute == 00){
tts.speak("The time is 1 O'clock", TextToSpeech.QUEUE_FLUSH,null);
}
else if (Hour == 2 && Minute == 00){
tts.speak("The time is 2 O'clock", TextToSpeech.QUEUE_FLUSH,null);
}
else if (Hour == 3 && Minute == 00){
tts.speak("The time is 3 O'clock", TextToSpeech.QUEUE_FLUSH,null);
}
else if (Hour == 4 && Minute == 00){
tts.speak("The time is 4 O'clock", TextToSpeech.QUEUE_FLUSH,null);
}
else if (Hour == 5 && Minute == 00){
tts.speak("The time is 5 O'clock", TextToSpeech.QUEUE_FLUSH,null);
}
if (Hour == 6 && Minute == 00){
tts.speak("The time is 6 O'clock", TextToSpeech.QUEUE_FLUSH,null);
}
handler.postDelayed(this, 1000);
}
};
handler.post(runnable);
}
#Override
public void onInit(int status) {
if (status == TextToSpeech.SUCCESS) {
int result = tts.setLanguage(Locale.US);
if (result == TextToSpeech.LANG_MISSING_DATA
|| result == TextToSpeech.LANG_NOT_SUPPORTED) {
Log.e("TTS", "Language not supported");
} else {
}
} else {
Log.e("TTS", "Initialization Failed!");
}
}
#Override
public void onDestroy() {
// Don't forget to shutdown tts!
if (tts != null) {
tts.stop();
tts.shutdown();
}
super.onDestroy();
}
}
I am afraid you created an infinite loop. You created the Runnable and submitted it to the queue handler.post(runnable);. Then inside the run() method you submit it with 1 second delay on with handler.postDelayed(this, 1000);.
This is why it's triggered every second. What time does the time_textView show?
There are better ways how to run scheduled tasks, check on JobScheduler for example
I'm not sure if this is "the right way" to do it, but for the sake of "code sanity" this would be my approach (posting only the modified code):
...
// we move this here, as there's no need to initialize it every time
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("h:mm:ss", Locale.getDefault());
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
# Override
public void run() {
Calendar calendar = Calendar.getInstance();
// we save our "now" as a reference so it does not "drift"/"shift" while the code is running
Date time = calendar.getTime();
String currentTime = simpleDateFormat.format(time);
time_textView.setText(currentTime);
// use lowercase for the first letter of variable names otherwise it gets confusing ...
// for ex. my variable "time" of type Date, if it was named "Time" ...
// when I would write "Time.getHours()" to get the hours ... One might think that there's a
// Class named "Time" ('cause classes usually start with capital letters) and this class has
// some static method "getHours", so who reads the code is forced to check to see that it was a variable
hour = time.getHours();
minute = time.getMinutes();
seconds = time.getSeconds();
if (minute == 0 && seconds == 0) {
// as said in some comment before, you should only check the minutes and seconds
// the message string could be a constant and insert the hour value using String.format()
// for optimized performance, but my Java skills are too rusty for that right now
tts.speak("The time is " + hour + " O'clock", TextToSpeech.QUEUE_FLUSH, null);
}
handler.postDelayed(this, 1000);
// actually here instead of delaying for 1 second ... you could calculate the "remaing time", how many seconds are
// missing until the next XX:00:00, and delay for that much
// for extra "precision", just in case, ... delay only for something like "remaingTime - 10" (or something) and
// if the "remaingTime < 10" delay only for 1 second, this way you can be more sure you'll not be missing the
// XX:00:00 ... but do this only if you notice "imprecisions" while using postDelayed with long intervals
// and you care about them
}
};
handler.post(runnable);
...

Countdown timer do not want to stop in java

I am trying to creating countdown timer using java with Netbeans 8.1 IDE,, My problem is when the timer gets 00:00 it do not want to stop..I have trying to write timer.stop(); but it still not working...Maybe you can help me ..
this is my source code :
ActionListener action;
action = new ActionListener() {
public void actionPerformed(ActionEvent e) {
seconds--;
if(seconds==0){
minutes--;
seconds=60;
}
if(seconds==0 && minutes==0){
timer.stop();
}
String min = minutes <= 9? "0"+minutes:minutes+"";
String seg = seconds <= 9? "0"+seconds:seconds+"";
txtRemaining.setText(min+":"+seg);
}
};
this.timer = new Timer(interval, action);
this.timer.start();
Your problem is here:
if(seconds==0 && minutes==0){
timer.stop();
}
seconds can never == 0 here since just before this block of code you call:
if(seconds==0){
minutes--;
seconds=60;
}
and if seconds == 0, you set it immediately to 60. The solution is to swap these two lines:
// call this **first**
if(seconds==0 && minutes==0){
timer.stop();
}
// call this **second**
if(seconds == 0){
minutes--;
seconds = 60;
}

Make countdown timer go from 10sec to 1sec

I have a CountDown timer that counts down from 10000ms to 0ms in increments of 1 second each to make a button clickable after 10 seconds. Although the timer is accurate and does what the code says, I would like to change the way the seconds are expressed but I don't know how.
java:
void startTimer() {
cTimer = new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
c.setText("Please wait " + millisUntilFinished/1000 + " seconds");
thx.setText(millisUntilFinished/1000 + "");
thx.setAlpha(.5f);
thx.setClickable(false);
}
public void onFinish() {
c.setText("done");
thx.setText("ready");
thx.setAlpha(1f);
thx.setClickable(true);
}
};
cTimer.start();
}
Outputted (Every second): 9, 8, 7, 6, 5, 4, 3, 2, 1, (still 1), ready
Desired: (Every second): 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, ready
Thanks,
B
EDIT:
I added 1 to the countdown, thx.setText(((millisUntilFinished/1000) + 1) + "");
New output: 10, 9, 8, 7, 6, 5, 4 ,3 , 2, (Still 2), ready
Closer... but not quite.
This is just my investigation on CountDownTimer when I used CountDownTimer
few month before and its work fine in my application.
public void onTick(long millisUntilFinished)
This millisUntilFinished will give the remaining time in millisecond, and last 1000 millisecond is to call onFinish() method, So onTick method will get called until the remaining time is more than (1000(for OnFinish) + 1000(for counter)) milliseconds, if the last remaining millisecond is less than 2000millisecond it will skip the onTick() and it will directly call onFinish() when timer ends. For more details just see Handler method in this source.
So the main problem is when we give some X(our case 10000)milliseconds, but to start the counter it's taking some 50 to 150 milliseconds, So if we add that millisecond in our total time we will get the counter until end,
So you can try like this, Nothing change just I added 150 milliseconds in your total time.
void startTimer() {
cTimer = new CountDownTimer(10150, 1000) {
public void onTick(long millisUntilFinished) {
c.setText("Please wait " + millisUntilFinished/1000 + " seconds");
thx.setText(millisUntilFinished/1000 + "");
thx.setAlpha(.5f);
thx.setClickable(false);
}
public void onFinish() {
c.setText("done");
thx.setText("ready");
thx.setAlpha(1f);
thx.setClickable(true);
}
};
cTimer.start();
}
Let me know if its works or not, If you ask me why you are not using Handler, I can say CountDownTime internally using Handler.
Try this one for counter:
public void CountDown() {
final TextView textic = (TextView) findViewById(R.id.tvConuter);
CountDownTimer Count = new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
long str = millisUntilFinished / 1000;
String TimeFinished = String.valueOf(str);
textic.setText(TimeFinished);
}
public void onFinish() {
textic.setText("STOP");
}
};
Count.start();
}
This worked perfectly for me.
I would suggest to use Timer() or Handler() class.
int tick = 0;
Handler handler = new Handler();
Runnable r = new Runnable() {void run(){
if (i < 10) {
handler.postDelayed()}
else {
//finished
tick = 0;
}}};
starting:
handler.post(r);
new CountDownTimer(10000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds: " + millisUntilFinished / 1000);
//here you can have your logic to set text to edittext
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
private void countDownTimer(int seconds) {
countDownTimer = new CountDownTimer(seconds * 1000L, 1000 - 500) {
public void onTick(long millisUntilFinished) {
//Convert to seconds
int secondsUnillFinished = (int) (millisUntilFinished / 1000);
//Set text to seconds
textView.setText(String.valueOf(secondsUnillFinished));
//At zero, do something
if(secondsUnillFinished == 0) {
countDownTimer.cancel();
textView.setVisibility(View.INVISIBLE);
}
}
#SuppressLint("SetTextI18n")
public void onFinish() {
//Dont put anything here
}
}.start();
}

Android Timer stops after updating TextView

i am trying to update a TextView every 5 seconds with a random number.
Unfortunately the timer stops when i call the .setText-function (i commented it out, it is because of this specific statement). I call the Timer in the onCreate()-Method of the Activity.
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
Random r = new Random();
count = r.nextInt(10);
String degree = Integer.toString(count);
mDegrees.setText(degree);
showToast();
}
}
, 1, 5, TimeUnit.SECONDS);
}
Also showToast() is not called. Why is that?
Best regards,
Max

testing code on time interval

Hi I want to run code over a time period. For example i would like my code to do something like this.
for(every 5 minutes until i say to stop)
automatically read in new value for x
automatically read in new value for y
if (x==y)
//do something
if (x!=y)
//do something else
Timer is what you need.
Naive version. You might consider Timer or the quartz scheduler instead.
while (!done) {
try {
Thread.sleep(5 * 60 * 1000);
x = readX();
y = readY();
if (x == y) {
} else {
}
} catch(InterruptedException ie) {
}
}
System.currentTimeMillis(); Returns you the system time in milliseconds, you can use that.
but first, you need some sort of loop.
This is an alternative to Timer 's
public static final int SECONDS = 1000;
public static final int MINUTES = 60 * SECONDS;
boolean quit = false; //Used to quit when you want to..
long startTime = System.currentTimeMillis();
while (!quit) {
if (System.currentTimeMillis() >= (startTime + (long)5*MINUTES)) {
//automatically read in new value for x
//automatically read in new value for y
if (x==y) {
//do something
} else {
//do something else
}
startTime = System.currentTimeMillis(); //reset the timer for the next 5 minutes
}
}
How about:
Runnable runnable = new Runnable() {
public void run() {
// do your processing here
}
};
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
service.scheduleAtFixedRate(runnable, 0, 5, TimeUnit.MINUTES);
Call service.shutdown() when you want to stop.

Categories