android - countdown timer is not canceling - java

In my app the user gets a point, when he clicks a button within 5 seconds. After that the timer should be canceled and restart. The problem I have is that the timer countinues counting down until it restarts. Is it set up wrong, or doesn't cancel(); stop the timer at all?
public class MainActivity extends AppCompatActivity {
Button btn;
TextView text;
TextView scoretv;
private static final String FORMAT = "%02d:%02d";
public int score = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scoretv = (TextView) findViewById(R.id.textView3);
btn = (Button) findViewById(R.id.button1);
text = (TextView) findViewById(R.id.textView2);
}
public void onClick(View view) {
score++;
scoretv.setText(String.valueOf(score));
load();
}
private void load() {
// TODO Auto-generated method stub
new CountDownTimer(5000, 10) { // adjust the milli
// seconds here
public void onTick(long millisUntilFinished) {
text.setText(""
+ String.format(
"%02d:%03d",
TimeUnit.MILLISECONDS
.toSeconds(millisUntilFinished)
- TimeUnit.MINUTES
.toSeconds(TimeUnit.MILLISECONDS
.toMinutes(millisUntilFinished)),
TimeUnit.MILLISECONDS
.toMillis(millisUntilFinished)
- TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS
.toSeconds(millisUntilFinished))));
}
public void onFinish() {
text.setText("GameOver.");
cancel();
}
}.start();
}
}

Because you're calling cancel() in onFinish, the timer won't stop when the user clicks the button. What will happen instead is that the button will start a 5 second CountDownTimer and at the end of the timer, cancel() will be called. But what's the point of cancelling a timer when it's already finished?
To fix this, I'd suggest making a global instance of a CountDownTimer object, instantiate it in the onCreate method, and cancel it in the onClick method.
First, add this to your global scope,
CountDownTimer timer;
Then, add what you originally had before in the load method to your onCreate,
timer = new CountDownTimer(5000, 10) { // adjust the milli
// seconds here
public void onTick(long millisUntilFinished) {
text.setText(""
+ String.format(
"%02d:%03d",
TimeUnit.MILLISECONDS
.toSeconds(millisUntilFinished)
- TimeUnit.MINUTES
.toSeconds(TimeUnit.MILLISECONDS
.toMinutes(millisUntilFinished)),
TimeUnit.MILLISECONDS
.toMillis(millisUntilFinished)
- TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS
.toSeconds(millisUntilFinished))));
}
public void onFinish() {
text.setText("GameOver.");
//cancel(); <-this is redundant
}
}.start();
And call timer.cancel() in your onClick method,
public void onClick(View view) {
score++;
scoretv.setText(String.valueOf(score));
//load(); <-unnecessary
timer.cancel();
}
Lastly, I'd suggest getting rid of load since it's sort of unnecessary at this point.

Define variable
private final long timeLeftInMillis=60000;
Create class
public void startCountDown() {
countDownTimer = new CountDownTimer(timeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
//Edit text set with time remaining
int seconds = (int) (millisUntilFinished / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
etime.setText( String.format("%02d", minutes)
+ ":" + String.format("%02d", seconds));
}
#Override
public void onFinish() {
}
}.start();
}
I used this in a quiz app to reset timer when an answer is given. Therefore I called timer from the class that I used to add a new question.
private void newQuestion(){
if (countDownTimer!=null){
countDownTimer.cancel();
}
getNextQuestion();
}

Related

Running a method every second starting on button press

I need a timer to start any time I press a button (on the button itself) that shows how many seconds it's been since it's pressed in real time. Whenever it's pressed again, timer is reset to 0 and starts incrementing again
I know this isn't the way to do it, the button works fine but the timer should be in onCreate? I'm not sure how this is supposed to work with a button
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
downloadedImg = (ImageView) findViewById(R.id.imageView);
}
public void clickAsync(View view) {
new ImageDownloader().execute(downloadUrl);
int seconds = 0;
Button button = (Button) view;
button.setText("Seconds since clicked: " + seconds);
Timer timer = new Timer();
//each time button is clicked, time is reset to 0 and increments in real time
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
seconds = 0;
seconds++;
button.setText("Seconds since clicked: " + seconds);
}
}, 0, 1000);
}
}
Another easy way to do this is to use Handler
mHandler = new Handler();
Just call updateSec();method on click of a button it'll update sec in interval of one seconds
Runnable UpdateRunnable = new Runnable() {
#Override
public void run() {
updateSec();
}
};
public void updateSec() {
mSeconds++;
mHandler.postDelayed(UpdateRunnable, 1000);
}
Example
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mSeconds = 0;
updateSec();//it'll update sec variable every second.
}
});
try this: use a handler
long startTime = 0;
long elapsedTime ;
//runs without a timer by reposting this handler at the end of the runnable
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
int hours = minutes / 60;
seconds = seconds % 60;
//textview for displaying time..
timerTextView.setText(String.format("%d:%02d:%02d", hours, minutes, seconds));
timerHandler.postDelayed(this, 1000);
}
};
b.setOnClickListener(new View.OnClickListener() { //b is your button
#Override
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals("Stop")) {
elapsedTime = System.currentTimeMillis() - startTime;
timerHandler.removeCallbacks(timerRunnable);
b.setText("Resume");
} else {
startTime = System.currentTimeMillis() - elapsedTime;
timerHandler.postDelayed(timerRunnable, 0);
Calendar cs = Calendar.getInstance();
System.out.println("Current time => " + cs.getTime());
SimpleDateFormat df = new SimpleDateFormat("HH:mm");
String formattedDate = df.format(cs.getTime());
timerTextView.setText(formattedDate);
b.setText("Stop");
}
}
});
it will calculate the elapsed time and show time after stop...
You can use threads:
#Override
public void onClick(View view){
switch(view.getId()){
case R.id.button:
new Thread(new Runnable() {
#Override
public void run() {
try{
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
count++;
textView.post(new Runnable() {
#Override
public void run() {
textView.setText(count + "");
}
});
}
}
}).start;
break;
}
}
the view must be updated on main thread, and so you need to use post() method that has runnable instance as parameter.
Alternatively, you can also use AsyncTask.

Pausing a CountDownTimer whilst another one runs - Android

I have two countdown timers in my program, a longer one (120 sec) and a shorter one (3.5 sec). I want the 120 second timer to be paused whilst the 3.5 second timer is running, and for the longer timer to continue running whenever the 3.5 second timer isn't running. So the program starts with the 120 sec remaining whilst the 3.5 sec one runs, then when the 3.5 sec one runs the 120 sec one will start and only pause when the 3.5 sec one runs again (once users presses enter.) How would I do this?
final CountDownTimer loop = new CountDownTimer(3500, 1000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
number.setVisibility(View.GONE);
final TextView prompt = (TextView) findViewById(R.id.prompt);
prompt.setVisibility(View.VISIBLE);
prompt.setText(" Enter the number");
final EditText input = (EditText) findViewById(R.id.enterAnswer);
input.setVisibility(View.VISIBLE);
input.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
Editable answer = input.getText();
int finalAnswer = Integer.parseInt(String.valueOf(answer));
int finalLoadG1 = Integer.parseInt(String.valueOf(number.getText()));
input.setVisibility(View.GONE);
prompt.setVisibility(View.GONE);
if (finalAnswer == finalLoadG1) {
score++;
}
number.setVisibility(View.VISIBLE);
if (score>=0 && score<=2){
int loadG1 = generateG1.nextInt(89999)+10000;
number.setText(""+loadG1);
}
else if (score>=3 && score<=5){
int loadG1 = generateG1.nextInt(899999)+100000;
number.setText(""+loadG1);
}
else if (score>=6 && score<=9){
int loadG1 = generateG1.nextInt(8999999)+1000000;
number.setText(""+loadG1);
}
else if (score>=10 && score<=14){
int loadG1 = generateG1.nextInt(89999999)+10000000;
number.setText(""+loadG1);
}
else if (score>=15 && score<=20){
int loadG1 = generateG1.nextInt(899999999)+100000000;
number.setText(""+loadG1);
}
else if (score>=21) {
int loadG1 = generateG1.nextInt((int) 8999999999L)+1000000000;
number.setText(""+loadG1);
}
input.getText().clear();
start();
return true;
default:
}
}
return false;
}
});
}
}.start();
new CountDownTimer(120000, 1000) {
#Override
public void onTick (long millisUntilFinished) {
}
#Override
public void onFinish() {
TextView result = (TextView) findViewById(R.id.outcome);
result.setText("Score: "+ score);
TextView prompt = (TextView) findViewById(R.id.prompt);
prompt.setVisibility(View.GONE);
final EditText input = (EditText) findViewById(R.id.enterAnswer);
input.setVisibility(View.GONE);
loop.cancel();
number.setVisibility(View.GONE);
}
}.start();
I have asked this before, but was not given a valid answer unfortunately. Would be grateful if anyone is capable of answering this question. Please feel free to insert any code that'll help explain your answer. Many thanks in advance.
Ok, I will try to give an example, but no guarantee that this is exactly what you need:
create a global variable and the CountDownTimer objects:
Long remainingTime = 120000L;
ThreePointFiveSecondsTimer mThreePointFiveSecondsTimer;
HundredTwentySecondsTimer mHundredTwentySecondsTimer;
create the 120 seconds timer:
public class HundredTwentySecondsTimer extends CountDownTimer {
public HundredTwentySecondsTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
}
}
create the 3.5 seconds timer:
public class ThreePointFiveSecondsTimer extends CountDownTimer {
public ThreePointFiveSecondsTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
remainingTime = millisUntilFinished;//set the remaining time
}
#Override
public void onFinish() {
//start the 120 second countdowntimer again
mHundredTwentySecondsTimer = new MyCountDownTimer(remainingTime, 1000);
mHundredTwentySecondsTimer.start();
}
}
start the 120 second timer:
mHundredTwentySecondsTimer = new MyCountDownTimer(remainingTime, 1000);
mHundredTwentySecondsTimer.start();
Then, at any time, you decide to start the 3.5 timer:
mThreePointFiveSecondsTimer = new ThreePointFiveSecondsTimer (3500, 1000);
mThreePointFiveSecondsTimer.start();
mHundredTwentySecondsTimer.cancel();
mHundredTwentySecondsTimer = null;
That´s just the idea behind, but you have to adjust this to your needs. Sorry, but can´t give you all the stuff you need, that will be beyond the frame.
You can try like this (I have not tested but hope it will work)
public class MainActivity extends BaseActivity {
private long remainingTimeForTimer = 0;
private CountDownTimer mCountDownTimer
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Start first timer
test1(120 * 1000);
// now on the basis of remaining timer you can cancel current timer and after that second timer you can start that timer with remaining time
if(remainingTimeForTimer > 0)
{
test1(remainingTimeForTimer);
}
}
private void test1(long totalTimerTime)
{
mCountDownTimer = new CountDownTimer(totalTimerTime, 1000) {
#Override
public void onTick(long millisUntilFinished) {
remainingTimeForTimer = millisUntilFinished;
}
#Override
public void onFinish() {
//trialCount = 0;
}
};
mCountDownTimer.start();
}
#Override
protected void onDestroy() {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
super.onDestroy();
}
}
Resolved
I have resolved this issue after trying multiple times. I ended up putting the larger timer in the onFinish of the shorter one and setting the initial time of that longer timer equal to millisUntilFinished. Then I cancel the long timer when the user presses enter and it automatically starts with the updated time whenever the EditText box is displayed.

synchronized countdown timer- android development

I have an app that has one countdown timer that should show up the same for every user when they open the app. In order to do this, I have based the time that the users' phones show on Epoch time. I do the following calculations to (what I thought would...) ensure that each phone shows the same time, and that the countdown clock is continuous and accurate. However, every time I open the app up, the clock is at a totally different time, when I think it should be continuously counting down and resetting. What's wrong? I have included my code below:
private static final int COUNTDOWN_DURATION = 30; //time in seconds
private static final long BASE_TIME = 1470729402L; //an arbitrary Epoch time that I have picked as a reference point
private TextView tvTimer;
private Long currentTimeMillis;
private int finalTime;
private boolean firstTime;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
//set up basics
...
//set up timer
tvTimer = (TextView) findViewById(R.id.tvTimer);
firstTime = true;
setCurrentTime();
}
private void setCurrentTime() {
currentTimeMillis = System.currentTimeMillis();
long currentTimeSecs = currentTimeMillis/1000;
long timeDiff = currentTimeSecs - BASE_TIME;
//determines what spot the countdown timer is at when the app is started
finalTime = (int) (timeDiff % COUNTDOWN_DURATION);
resetTimer();
}
public void resetTimer(){
if (firstTime) {
CountDownTimer countDownTimer = new CountDownTimer(finalTime * 1000, 1000) {
public void onTick(long millisUntilFinished) {
tvTimer.setText(" " + millisUntilFinished / 1000 + " ");
}
public void onFinish() {
resetTimer();
}
};
countDownTimer.start();
firstTime = false;
}
else {
CountDownTimer countDownTimer = new CountDownTimer(COUNTDOWN_DURATION * 1000, 1000) {
public void onTick(long millisUntilFinished) {
tvTimer.setText(" " + millisUntilFinished / 1000 + " ");
}
public void onFinish() {
resetTimer();
}
};
countDownTimer.start();
}
}

Java/Android Countdown timer

i'm trying to make an countdown timer on Android with java. There are a timer a 25 minute study timer and a 5 minute break timer. I have both timers working. However, I don't know how to cancel/clear the timers. If I click I start a study timer and break timer they will both run simultaneously and I don't want that. I want the original timer to cancel when another timer is put on. This is the code.
btnStart.setOnClickListener(new OnClickListener() {
public void onClick(View v){
btnStart.setEnabled(false);
btnBreak.setEnabled(true);
breakBoolean = false;
CountDownTimer timer;
long amountOfStudyTime = 1500000; //30 seconds (may cause problems)
long countDownInterval = 1000; //1 second
//Initialise the countdown timer
timer = new CountDownTimer(amountOfStudyTime, countDownInterval){
public void onTick(long millisUntilFinished){
if( studyBoolean = false ) {
tViewTime.setText("CountDownTimer Canceled/stopped.");
cancel();
breakBoolean = true;
}else{
//display remaining seconds to user
tViewTime.setText(""+String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes( millisUntilFinished),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
}
}
public void onFinish(){
//When countdown is finished do...
breakBoolean = true;
int currentScore = Integer.parseInt(editScore.getText().toString());
int finalScore = currentScore + 5;
editScore.setText(Integer.toString(finalScore));
tViewTime.setText("Done");
}
}.start();
}
});
//Set a click listener for break button
btnBreak.setOnClickListener(new OnClickListener() {
public void onClick(View v){
btnStart.setEnabled(true);
btnBreak.setEnabled(false);
studyBoolean = false;
CountDownTimer timer2;
long amountOfBreakTime = 300000; //30 seconds (may cause problems)
long countDownInterval = 1000; //1 second
//Initialise the countdown timer
timer2 = new CountDownTimer(amountOfBreakTime, countDownInterval){
public void onTick(long millisUntilFinished){
if( breakBoolean = false ) {
cancel();
studyBoolean = true;
}else{
//display remaining seconds to user
tViewTime.setText(""+String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes( millisUntilFinished),
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished))));
}
}
public void onFinish(){
//When countdown is finished do...
tViewTime.setText("Done");
studyBoolean = true;
}
}.start();
}
});
Create two CountDownTimer objects in your activity and cancel them depending on your button selected :
public class MainActivity extends Activity {
boolean breakIsRunning = false;
boolean startIsRunning = false;
Button btnStart,btnBreak;
CountDownTimer startTimer = new CountDownTimer(amountOfStudyTime, countDownInterval)
{
#Override
public void onFinish() {
//do something
startIsRunning = false;
}
#Override
public void onTick(long arg0) {
//do something
startIsRunning = true;
}
};
CountDownTimer breakTimer = new CountDownTimer(amountOfBreakTime, countDownInterval)
{
#Override
public void onFinish() {
//do something
breakIsRunning = false;
}
#Override
public void onTick(long arg0) {
//do something
breakIsRunning = true;
}
};
//->OnCreate() - >Buttons code
btnStart.setOnClickListener(new OnClickListener().. { // your listener code here
if(breakIsRunning)
breakTimer.cancel();
startTimer.start();
}
btnBreak.setOnClickListener(new OnClickListener().. { //
if(startIsRunning)
startTimer.cancel();
breakTimer.start();
}
}

How can I destroy a CountDownTimer in Android?

I have this code in a BroadcastReceiver that should change a textview with the word "CHARGING" if the phone is plugged or with a Count Down Timer if it is not:
int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
TextView textView2 = (TextView) findViewById(R.id.textView2);
TextView textView3 = (TextView) findViewById(R.id.textView3);
String str = Boolean.toString(isCharging);
textView2.setText(str);
CountDownTimer aCounter = new CountDownTimer((long) timeleft, 1000) {
public void onTick(long millisUntilFinished) {
long seconds = millisUntilFinished / 1000;
mTextField.setText(String.format("%02d:%02d:%02d", seconds / 3600,
(seconds % 3600) / 60, (seconds % 60)));
}
public void onFinish() {
mTextField.setText("done!");
}
};
if (usbCharge || acCharge ) {
textView3.setText("Charging");
mTextField.setText("CHARGING");
aCounter.cancel();
aCounter = null;
}
else {
textView3.setText("Not Charging");
mTextField.setText("NOT CHARGING");
aCounter.start();
}
}
My problem is if I start the app with the phone plugged I can see the word "CHARGING" in the textview, when I unplug the phone I can see the count down timer, but when I plug the phone again, I only see the word "Charging" a millisecond and then I see the count down timer again. And if I unplug the phone again, I see two count down timers at the same time in the same textview.
It is like I create a new count down timer every time I plug the phone without destroy the previous one.
Oh ok, first of all, don't make CountDownTimer class like that
/* Declare a class level object */
private MyCountDownTimer myCountDownTimer;
private class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long millisInFuture,
long countDownInterval) {
super(millisInFuture, countDownInterval);
// TODO Auto-generated constructor stub
}
#Override
public void onTick(long millisUntilFinished) {
//TODO some code here
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
}
}
then when you want to start countdown timer
myCountDownTimer = new MyCountDownTimer(
999999999999999999L, 15 * 1000);
myCountDownTimer.start();
and when you want to cancel that
if(myCountDownTimer!=null)
{
myCountDownTimer.cancel();
}

Categories