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.
Related
I am trying to learn coding. So I decided to make a little project but i stuck.
I am trying to make a CountDownTimer. I have 3 different times. For example first one is 10 sec, second one 5 sec and the third one is 7 sec. So I wanna make an app that start the count from 10 sec and when it finish it start the count from second timer and then third one.
public class MainActivity extends AppCompatActivity {
private Button mStartButton;
private Button mResetButton;
private Button mStopButton;
private TextView mTextViewCountDown;
private TextView mTextViewCounter;
private CountDownTimer mCountDownTimer;
private int countme = 0 ;
private int [] array = new int[3];
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStartButton = findViewById(R.id.button_start);
mStopButton = findViewById(R.id.button_stop);
mResetButton = findViewById(R.id.button_reset);
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mTextViewCounter = findViewById(R.id.text_s);
array[0]=10000;
array[1]=5000;
array[2]=70000;
mStartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for(int i = 0; i<3; i++){
mCountDownTimer = new CountDownTimer(array[i], 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTextViewCountDown.setText(""+ millisUntilFinished/1000);
}
#Override
public void onFinish() {
countme++;
if(countme / 3 == 3){
mCountDownTimer.cancel();
}else{
start();
} } }.start();
}
}
}); } }
I don't think for loop is right for my problem. It does not increase variable i once, it increase in every ontick i guess. As a beginner, I couldn't figure out what should I do.
You do not need for loop try something like this:
private void startCountDowntimer(long millis, int count) {
count ++;
int finalCount = count;
new CountDownTimer(millis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTextViewCountDown.setText(""+ millisUntilFinished/1000);
}
#Override
public void onFinish() {
if (finalCount == 1) {
startCountDowntimer(5000, 1);
} else if (finalCount == 2) {
startCountDowntimer(7000, 2);
} else {
//all finished
}
}
}.start();
}
and on the button click:
mStartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startCountDowntimer(10000, 0);
}
});
I'm making a timer which has a button I can control either pick the count-up mode or countdown mode. The count down mode is working perfectly, start, pause, reset. The count-up timer is made by reversing the countdown timer in Android studio. the problem is I can't pause the count-up timer and resume from where it stops.
What's the proper way to do that? I know it could be done by chronometer for count-up mode, but I'm trying to make a customized timer widget that as I mentioned before, a button could be pressed to let the user decide which mode he wants. So if possible, I don't want to use another widget in my current set up.
public void startBuiltInTimer(int millisecondCountingInterval) {
if (getTimeInMillis() > 0) { //getTimeInMillis will read the time value in the current Timer widget, which is a textView
builtInTimerIsCounting = true; //set the timer is running flag
showAsCounting(true);
if (getTimerCountUpOrDown() == TIMER_COUNT_DOWN) { //countdown mode
countDownTimer = new CountDownTimer(getTimeInMillis(), millisecondCountingInterval) {
#Override
public void onTick(long millisUntilFinished) {
setTime(millisUntilFinished);
}
}
#Override
public void onFinish() {
setTime(0);
builtInTimerIsCounting = false;
showAsCounting(false);
}
}
}.start();
} else if (getTimerCountUpOrDown() == TIMER_COUNT_UP) { //count up mode
long tempTimeInMillis = getTimeInMillis() + lastTimeMillisUntilFinished; //trying to save the last time value in millis and keep the total time value as user defined.
setTime(0); //set initial value of the textView to show the count-up timer start from zero, initially.
countDownTimer = new CountDownTimer(tempTimeInMillis, millisecondCountingInterval) {
#Override
public void onTick(long millisUntilFinished) {
long temp = tempTimeInMillis - millisUntilFinished;
setTime(temp); //reverse the countdown to count-up
lastTimeMillisUntilFinished = millisUntilFinished;//keep the millisUntilFinished for next start.
}
#Override
public void onFinish() {
setTime(tempTimeInMillis);
builtInTimerIsCounting = false;
showAsCounting(false);
}
}
}.start();
}
}
}
Edit:
I end up to use SystemClock to keep tracking and record the count up timer. Here is the code.
else if (getTimerCountUpOrDown() == TIMER_COUNT_UP) {
startCountUpTimer(millisecondCountingInterval);
}
public void startCountUpTimer(int millisecInterval) {
if (!countUpTimerIsRunning) {
handler = new Handler();
myRunnable = new MyRunnable(millisecInterval); //MyRunnable can pass a variable thru to let handler have more flexibility with postDelay method. You can still use regular Runnable with hard coded time interval in millisec.
startTime = SystemClock.uptimeMillis(); //use startTime to mark the time when the count up timer start ticking
handler.postDelayed(myRunnable, millisecInterval);
countUpTimerIsRunning = true;
}
}
public class MyRunnable implements Runnable {
private int interval;
public MyRunnable(int t) {
this.interval = t;
}
#Override
public void run() {
millisecondTime = SystemClock.uptimeMillis() - startTime; //this is the time value measured by the count up timer
updateTime = timeBuff + millisecondTime;
setTime(updateTime);
if (updateTime <= countUpMode_Threshold) {
handler.postDelayed(this, interval);
} else {
setTime(countUpMode_Threshold);
handler.removeCallbacks(myRunnable);
builtInTimerIsCounting = false;
showAsCounting(false);
if (onBuiltInTimerStatusChangeListener != null) {
onBuiltInTimerStatusChangeListener.onStatusChange(OnBuiltInTimerStatusChangeListener.STATUS_FINISHED);
}
}
}
}
public void pauseCountUpTimer() {
timeBuff += millisecondTime;
handler.removeCallbacks(myRunnable);
countUpTimerIsRunning = false;
}
One way is that you should keep track of the pause time manually and start timer from that time again. Or you can try using the utility at this link It has the functionality you are looking for.
Pretty helpful
Maybe something like this:
private CountDownTimer timer;
private long COUNT_DOWN = -1;
private long COUNT_UP = 1;
public void startBuiltInTimer(boolean isDown) {
if (isdown) {
launchTimer(COUNT_DOWN);
} else {
launchTimer(COUNT_UP);
}
}
public void launchTimer(long interval) {
builtInTimerIsCounting = true; //set the timer is running flag
showAsCounting(true);
timer = new CountDownTimer(getTimeInMillis(), TimeUnit.SECONDS.toMillis(interval) {
#Override
public void onTick(long time) {
setCountdownText(time.intValue());
setTimeInMillis(time);
}
#Override
public void onFinish() {
setCountdownText(time.intValue());
builtInTimerIsCounting = false;
showAsCounting(false);
}
}.start();
public void stopTimer() {
timer.cancel();
}
...
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();
}
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();
}
}
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();
}