I want to use a Countdown Timer but have a problem. If i start it and then press a Back button (change lifecycle to onStop) and return back to activity - i cant see timer values in TextView. But in Logcat i see that the timer works.
Question: how to update TextView after return on activity (onResume)
UPDATE.
While i'll not close activity this code works as it should - well. But if i press back button there is no values in TextView.
The timer method code (this method is called from onCreate):
timer = new CountDownTimer(rest + 1000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
secondsUntilFinish = Math.round(millisUntilFinished / 1000);
String minutes = String.format("%02d",TimeUnit.SECONDS.toMinutes(secondsUntilFinish));
String seconds = String.format("%02d",TimeUnit.SECONDS.toSeconds(secondsUntilFinish) - TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(secondsUntilFinish)));
tvRoutineTimer.setText(getResources().getString(R.string.exercise_rest_timer, minutes, seconds));
Log.d(LOG_TAG, "onTick = " + getResources().getString(R.string.exercise_rest_timer, minutes, seconds));
}
#Override
public void onFinish() {
tvRoutineProgress.setText(getString(R.string.routine_progress, currentStep, totalSteps));
tvRoutineTimer.setText(getString(R.string.exercise_rest_timer, "00", "00"));
notificationAfterRest();
btnExerciseDone.setText(getString(R.string.button_exercise_done));
btnExerciseDone.setEnabled(true);
tvExercisePlaceholder.setText(getString(R.string.exercise_current_title));
}
}.start();
You need to update your TextView from the UI thread. Update your TextView like this:
runOnUiThread(new Runnable() {
#Override
public void run() {
tvRoutineTimer.setText(getResources().getString(R.string.exercise_rest_timer, minutes, seconds));
});
Place the runOnUiThread inside the onTick()
Related
I'm creating a quiz app in android. I have written OnClickListener for next button to load next question. now I want to add timer to each question so that when timer ends it will automatically call OnClickListener of next button. How to implement this?
If you want to delay some code from running for a certain amount of time use a Runnable and a Handler like this
Runnable r = new Runnable() {
#Override
public void run(){
doSomething(); //<-- put your code in here.
}
};
Handler h = new Handler();
h.postDelayed(r, 1000);
You just need to call performClick() on an instance of your next button. Something like this:
nextButton.performClick()
That will execute everything you have inside of OnClickListener that is set for that button.
EDIT:
If I misunderstood your question and you are searching for Timer implementation, I recommend for you check CountDownTimer that is provided by Android team. You can check documentation with an example for his here:
https://developer.android.com/reference/android/os/CountDownTimer
You can have a method you call when the user clicks the next button say it's named as nextQuestion()
then add the listener of your next button
Button nextBtn = findViewById(..);
nextBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
nextQuestion();
}
});
And the time would be CountDownTimer of say 1 min duration (60*1000 msec) and 1 second tick (1000 msec)
new CountDownTimer(60000, 1000) { // 1 min duration (60*1000 msec) and 1 second tick (1000 msec)
#Override
public void onTick(long millisUntilFinished) {
// do something each second
}
#Override
public void onFinish() {
// timer expired
nextQuestion();
}
}.start();
I have a problem with countdown timer.I try some of solutions and articles in this site but they never worked for me. so, please read my codes...
also I used
handler.postDelayed(new Runnable() {
before and it was not my solution but it just worked correctly.
Main question is:
I want to do something like below:
(button pressed)
do some codes1
delay1
do other codes2
delay2
go back to *do some codes1* again.
In short, this is my real code:
itimesec--;
setdelay();
irepeat--;
setrelax();
and this is in my functions:
public void setrelax(){
CountDownTimer yourCountDownTimer1 = new CountDownTimer(50000, 1000) {
public void onTick(long millisUntilFinished1) {
itotalsnozee--;
TextToSpeechFunction(" "+itotalsnozee);
}
public void onFinish() {
itotalsnozee=fitotalsnozee;
isrelax=false;
TextToSpeechFunction("do again");
}
}.start();
yourCountDownTimer1.cancel();
}
I tried to use a variable insted of 50000 but it was not useful anyway.
I tried to put setrelax funtion codes directly into oncreate but it never worked.
it just jumped to
}.start();
yourCountDownTimer1.cancel();
every times and go out.
I tried all the codes without any delay function and they runned correctly.
what is my wrong please...
You need to remember that your code won't be executed sequentially when using the CountDownTimer because it's working asynchronously (via Handler).
Let's dissect your code. Your following code here:
public void setrelax(){
// 1. Creating CountDownTimer
CountDownTimer yourCountDownTimer1 = new CountDownTimer(50000, 1000) {
public void onTick(long millisUntilFinished1) {
// 2. onTick called
...
}
public void onFinish() {
// 3. onFinish called
...
}
}.start();
// 4. CountDownTimer is cancelled.
yourCountDownTimer1.cancel();
}
will be running in the following sequences:
Creating CountDownTimer
CountDownTimer is cancelled.
onTick called 49 times repeatedly (50000/1000 = 50 - 1 ).
onFinish called
So, change your algorithm to something like this:
do some codes1
delay1
--> When delay finished, do other codes2. Then do delay2
You need to call the next code in the CountDownTimer.onFinish()
I looked at your code and I could not find any big mistakes but try this instead
Instead of
.start();
use
yourCountDownTimer1.start();
and remove yourCountTimer1.cancel();
like this :
public void setrelax(){
CountDownTimer yourCountDownTimer1 = new CountDownTimer(50000, 1000) {
public void onTick(long millisUntilFinished1) {
itotalsnozee--;
TextToSpeechFunction(" "+itotalsnozee);
}
public void onFinish() {
itotalsnozee=fitotalsnozee;
isrelax=false;
TextToSpeechFunction("do again");
}
};yourCountDownTimer1.start();
}
Hope it helps.
below is the code for running otp timer in our code.you can copy paste i have mentioned the comments please follow the same.
CountDownTimer countDownTimer; //define countDownTimer
countDownTimer.start(); // start countdown timer on some event like on click
String x="Your code will expire In";
String y="mins";
counttimer(); call the method counttimer which includes all the code of timer
public void counttimer(){
countDownTimer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
String text = String.format(Locale.getDefault(), x+" %02d : %02d "+y,
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60);
phonever_timer.setText(text); //set timer into textview object
}
public void onFinish() {
phonever_timer.setText("Otp Expired..!");
}
};
I have an edit text for entering a time in minutes, a button to start a countdown timer using the minutes entered in the edit text which updates a text view, and a button which I want to cancel the countdown timer before it finishes.
The problems I'm having are...the variable the countdown timer needs (the milliseconds) can't get assigned until I click the start timer button because it's coming from an edit text. So I created the countdown timer inside of the onClick for the start timer button. However...I want another button to cancel the timer...and it doesn't have access to the countdown timer. So that didn't solve anything and I'm confused at how to do this. Any advice would help.
Edit: I just realized I could move the stop timer button with the listener to the start timer button onClick also...under the countdown timer. I'm just confused about how the countdown timer could find the milliseconds variable if I have countdown timer outside of the start timer onClick. I guess moving the stop timer under countdown timer works...but still feels like I'm missing something.
Edit2: I tried moving countDownTimer into onCreate and making milliseconds global...but I have to make countDownTimer final in order for the buttons to be able to use it, and countDownTimer just skips to onFinish.
mTimerTextView = (TextView)findViewById(R.id.timer_text_view);
mTimerEditText = (EditText)findViewById(R.id.timer_edit_text);
mStartTimerButton = (Button)findViewById(R.id.btn_start_timer);
mStartTimerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Getting time in minutes from edit text
int timeEntered = Integer.parseInt(mTimerEditText.getText().toString());
long milliseconds = timeEntered * 60000;
CountDownTimer countDownTimer = new CountDownTimer(milliseconds, 1000) {
#Override
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000) % 60;
int minutes = (int) ((millisUntilFinished / (1000*60)) % 60);
int hours = (int) ((millisUntilFinished / (1000*60*60)) % 24);
mTimerTextView.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
}
#Override
public void onFinish() {
new AlertDialog.Builder(DailyGoalActivity.this)
.setTitle("Time's Up")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}).show();
}
};
countDownTimer.start();
}
});
mStopTimerButton = (Button)findViewById(R.id.btn_stop_timer);
mStopTimerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// countDownTimer.cancel(); <- How could I do this?
}
});
there are two possible reason for your problem first one is that you need to create countdown timer in onCreate and second one is that you are stopping null countdown timer.
solution-1 you can use a boolean variable to check that timer has start or not and then start timer accordingly on button click.Apart from this initialize timer in on create and start in on click follow this code please follow this link
solution-2 to stop the timer use this code
if(countDownTimer != null) {
countDownTimer .cancel();
countDownTimer = null;
}
Isn't the simple solution to declare CountDownTimer variable globally?
Move this code to onCreate
CountDownTimer countDownTimer = new CountDownTimer(milliseconds, 1000) {
#Override
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000) % 60;
int minutes = (int) ((millisUntilFinished / (1000*60)) % 60);
int hours = (int) ((millisUntilFinished / (1000*60*60)) % 24);
mTimerTextView.setText(String.format("%02d:%02d:%02d", hours, minutes, seconds));
}
}
Then start timer in Start button's onClick and cancel in Stop button's onClick.
Hope it helps.
I have one CountDownTimer and i want to do an action for every two wasted seconds.
countdowntimer = new CountDownTimer(10000, 1) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
}
}.start();
For example when it starts time remaining = 10 seconds
When time remaining = 8 seconds I want to do an action
When time remaining = 6 seconds I want to do an action
and so on......
Just check if it is divisible by 2.
#Override
public void onTick(long millisUntilFinished) {
long seconds = millisUntilFinished/1000;
if ((seconds % 2) == 0)
{ // even number--do some action }
}
This is assuming you are calling the onTick() every second like
countdowntimer = new CountDownTimer(10000, 1000) {
This is probably preferable for you
Setting it up to call every 2 seconds should also work and better but leaving the original answer in case someone needs to call onTick() more often
countdowntimer = new CountDownTimer(10000, 2000) {
then you could just do the action with every call to onTick()
CountDownTimer Docs
I'm extending the CountDownTimer class to obtain some custom functionality .In onTick() in case some conditions are met I call cancel() , expecting that will be the end of it, however the onTick() callback gets call until the the count down is reached . So how to prevent this from happening ?
CountDownTimer.cancel() method seems to be not working. Here's another thread without a solution Timer does not stop in android.
I would recommend you to use Timer instead. It's much more flexible and can be cancelled at any time. It may be something like that:
public class MainActivity extends Activity {
TextView mTextField;
long elapsed;
final static long INTERVAL=1000;
final static long TIMEOUT=5000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextField=(TextView)findViewById(R.id.textview1);
TimerTask task=new TimerTask(){
#Override
public void run() {
elapsed+=INTERVAL;
if(elapsed>=TIMEOUT){
this.cancel();
displayText("finished");
return;
}
//if(some other conditions)
// this.cancel();
displayText("seconds elapsed: " + elapsed / 1000);
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, INTERVAL, INTERVAL);
}
private void displayText(final String text){
this.runOnUiThread(new Runnable(){
#Override
public void run() {
mTextField.setText(text);
}});
}
}
CountDownTimer is also working fine for me, but I think it only works if you call it OUTSIDE of the CountDownTimer implemetation (that is don't call it in the onTick).
Calling it inside also didn't worked.
I tried this code snippet, since most answers are saying you cannot cancel the timer inside its implementation, thus i tried using a handler inside onFinish. Old post but if anyone comes across this its helpful.
new Handler().post(new Runnable() {
#Override
public void run() {
timerTextView.setText("00:" + String.format("%02d", counter));
cancel();
}
});