Calculate the Time used by CountDownTimer Once it's started in java? - java

I have countdowntimer Code which is working fine. But i want to calculate the time which is over once couterdowntimer is started running.
ex. If i have 2 hours running in countdowntimer. once it starts running i want to calculate time which is used like 2:00:00 hrs - 1:45:00 = 0:15:00
And show that time over in TimeOver TextView.
It should be dynamically changed along with countdowntimer running.
UI Screenshot:
This is my Code.
public class MainActivity extends AppCompatActivity {
private EditText mEditTextInput;
private TextView mTextViewCountDown,mTextTimeOver;
private Button mButtonSet;
private Button mButtonStartPause;
private Button mButtonReset;
private CountDownTimer mCountDownTimer;
private boolean mTimerRunning;
private long mStartTimeInMillis;
private long mTimeLeftInMillis;
private long mEndTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditTextInput = findViewById(R.id.edit_text_input);
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mTextTimeOver = findViewById(R.id.text_view_timeOver)
mButtonSet = findViewById(R.id.button_set);
mButtonStartPause = findViewById(R.id.button_start_pause);
mButtonReset = findViewById(R.id.button_reset);
mButtonSet.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String input = mEditTextInput.getText().toString();
if (input.length() == 0) {
Toast.makeText(MainActivity.this, "Field can't be empty", Toast.LENGTH_SHORT).show();
return;
}
long millisInput = Long.parseLong(input) * 60000;
if (millisInput == 0) {
Toast.makeText(MainActivity.this, "Please enter a positive number", Toast.LENGTH_SHORT).show();
return;
}
setTime(millisInput);
mEditTextInput.setText("");
}
});
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
resetTimer();
}
});
}
private void setTime(long milliseconds) {
mStartTimeInMillis = milliseconds;
resetTimer();
closeKeyboard();
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
updateWatchInterface();
}
}.start();
mTimerRunning = true;
updateWatchInterface();
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
updateWatchInterface();
}
private void resetTimer() {
mTimeLeftInMillis = mStartTimeInMillis;
updateCountDownText();
updateWatchInterface();
}
private void updateCountDownText() {
int hours = (int) (mTimeLeftInMillis / 1000) / 3600;
int minutes = (int) ((mTimeLeftInMillis / 1000) % 3600) / 60;
int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
String timeLeftFormatted;
if (hours > 0) {
timeLeftFormatted = String.format(Locale.getDefault(),
"%d:%02d:%02d", hours, minutes, seconds);
} else {
timeLeftFormatted = String.format(Locale.getDefault(),
"%02d:%02d", minutes, seconds);
}
mTextViewCountDown.setText(timeLeftFormatted);
}
private void updateWatchInterface() {
if (mTimerRunning) {
mEditTextInput.setVisibility(View.INVISIBLE);
mButtonSet.setVisibility(View.INVISIBLE);
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setText("Pause");
} else {
mEditTextInput.setVisibility(View.VISIBLE);
mButtonSet.setVisibility(View.VISIBLE);
mButtonStartPause.setText("Start");
if (mTimeLeftInMillis < 1000) {
mButtonStartPause.setVisibility(View.INVISIBLE);
} else {
mButtonStartPause.setVisibility(View.VISIBLE);
}
if (mTimeLeftInMillis < mStartTimeInMillis) {
mButtonReset.setVisibility(View.VISIBLE);
} else {
mButtonReset.setVisibility(View.INVISIBLE);
}
}
}
private void closeKeyboard() {
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
#Override
protected void onStop() {
super.onStop();
SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong("startTimeInMillis", mStartTimeInMillis);
editor.putLong("millisLeft", mTimeLeftInMillis);
editor.putBoolean("timerRunning", mTimerRunning);
editor.putLong("endTime", mEndTime);
editor.apply();
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
}
#Override
protected void onStart() {
super.onStart();
SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
mStartTimeInMillis = prefs.getLong("startTimeInMillis", 600000);
mTimeLeftInMillis = prefs.getLong("millisLeft", mStartTimeInMillis);
mTimerRunning = prefs.getBoolean("timerRunning", false);
updateCountDownText();
updateWatchInterface();
if (mTimerRunning) {
mEndTime = prefs.getLong("endTime", 0);
mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
if (mTimeLeftInMillis < 0) {
mTimeLeftInMillis = 0;
mTimerRunning = false;
updateCountDownText();
updateWatchInterface();
} else {
startTimer();
}
}
}
}

Related

How to make repeated countdown timer

I am making cutdown timer and I wanna reapeat it after break. For example I set timer fo 4 second after this 4 seconds I wanna have 10 second break and then i wanna have timer again for 4 minutes
My timer look like that
long millisInput = Long.parseLong(input) * 60000;
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
resetTimer();
}
});
}
private void setTime(long milliseconds) {
mStartTimeInMillis = milliseconds;
resetTimer();
closeKeyboard();
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimerRunning = true;
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
updateWatchInterface();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if(counter++ < 5){
startTimer();
}
}
},10000);
}
}.start();
updateWatchInterface();
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
updateWatchInterface();
}
private void resetTimer() {
mTimeLeftInMillis = mStartTimeInMillis;
updateCountDownText();
updateWatchInterface();
}
private void updateCountDownText() {
int hours = (int) (mTimeLeftInMillis / 1000) / 3600;
int minutes = (int) ((mTimeLeftInMillis / 1000) % 3600) / 60;
int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
String timeLeftFormatted;
if (hours > 0) {
timeLeftFormatted = String.format(Locale.getDefault(),
"%d:%02d:%02d", hours, minutes, seconds);
} else {
timeLeftFormatted = String.format(Locale.getDefault(),
"%02d:%02d", minutes, seconds);
}
mTextViewCountDown.setText(String.valueOf(counter + 1) +" - "+timeLeftFormatted);
}
private void updateWatchInterface() {
if (mTimerRunning) {
mEditTextInput.setVisibility(View.INVISIBLE);
mButtonSet.setVisibility(View.INVISIBLE);
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setText("Pause");
} else {
mEditTextInput.setVisibility(View.VISIBLE);
mButtonSet.setVisibility(View.VISIBLE);
mButtonStartPause.setText("Start");
if (mTimeLeftInMillis < 1000) {
mButtonStartPause.setVisibility(View.INVISIBLE);
} else {
mButtonStartPause.setVisibility(View.VISIBLE);
}
if (mTimeLeftInMillis < mStartTimeInMillis) {
mButtonReset.setVisibility(View.VISIBLE);
} else {
mButtonReset.setVisibility(View.INVISIBLE);
}
}
}
private void closeKeyboard() {
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
#Override
protected void onStop() {
super.onStop();
SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong("startTimeInMillis", mStartTimeInMillis);
editor.putLong("millisLeft", mTimeLeftInMillis);
editor.putBoolean("timerRunning", mTimerRunning);
editor.putLong("endTime", mEndTime);
editor.apply();
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
}
#Override
protected void onStart() {
super.onStart();
SharedPreferences prefs = getSharedPreferences("prefs", MODE_PRIVATE);
mStartTimeInMillis = prefs.getLong("startTimeInMillis", 600000);
mTimeLeftInMillis = prefs.getLong("millisLeft", mStartTimeInMillis);
mTimerRunning = prefs.getBoolean("timerRunning", false);
updateCountDownText();
updateWatchInterface();
if (mTimerRunning) {
mEndTime = prefs.getLong("endTime", 0);
mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
if (mTimeLeftInMillis < 0) {
mTimeLeftInMillis = 0;
mTimerRunning = false;
updateCountDownText();
updateWatchInterface();
} else {
startTimer();
}
}
}
And after set for example one minute I wanna reapeat same time 5 times. ( IIIIIIIIIIIIIIIIIIIIIIIIIIII
Replace your code with this.
int timerMilliSecond = 4000;
CountDownTimer countDownTimer = new CountDownTimer(timerMilliSecond, 1000) {
#Override
public void onTick(long millisUntilFinished) {
tv2.setText("Przygotuj się:\n " + (millisUntilFinished / 1000));
}
public void onFinish() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
timerMilliSecond = 4 * 60000;
countDownTimer.start();
}
},1000);
}
}.start();
I hope it's helpful for you.
int counter = 0;
CountDownTimer countDownTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
countDownTimer = new CountDownTimer(4000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
int rounded = (int) (((millisUntilFinished + 999) / 1000 ) * 1000); // 4000,3000,2000,1000 ....
tv2.setText("Przygotuj się:\n " + (rounded / 1000));
}
public void onFinish() {
tv2.setText("Przygotuj się:\n " + 0);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if(counter++ < 5)
countDownTimer.start();
}
},10000); // repeat after ten seconds.
}
}.start();
}
if you don't want endless loop, you should use counter. So you can repeat five times.
#Override
public void onFinish() {
mTimerRunning = false;
updateWatchInterface();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if(counter++ < 5){
mTimerRunning = true;
startTimer();
}
}
},60000);
}

Countdown timer seems to be running in background even after I pause it after orientation change (portrait to landscape or vice versa)

I made a countdown timer and I want it to keep running even after orientation change. But say when I start the timer and then change orientation and then pause it, the timer seems to be running in the background.
I checked if it's running in background or not by displaying a toast message in onFinish() function and it seems to be running in the background.
import android.os.CountDownTimer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
private static final long START_TIME_IN_MILLIS = 10000;
private TextView mTextViewCountDown;
private Button mButtonStartPause;
private Button mButtonReset;
private CountDownTimer mCountDownTimer;
private boolean mTimerRunning;
private long mTimeLeftInMillis = START_TIME_IN_MILLIS;
private long mEndTime;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mButtonStartPause = findViewById(R.id.button_start_pause);
mButtonReset = findViewById(R.id.button_reset);
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
resetTimer();
}
});
updateCountDownText();
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
Toast.makeText(MainActivity.this, "TIMER RUNNING IN BACKGROUND..!!! ", Toast.LENGTH_SHORT).show();
updateButtons();
}
}.start();
mTimerRunning = true;
updateButtons();
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
updateButtons();
}
private void resetTimer() {
mTimeLeftInMillis = START_TIME_IN_MILLIS;
updateCountDownText();
updateButtons();
}
private void updateCountDownText() {
int minutes = (int) (mTimeLeftInMillis / 1000) / 60;
int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
mTextViewCountDown.setText(timeLeftFormatted);
}
private void updateButtons() {
if (mTimerRunning) {
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setText("Pause");
} else {
mButtonStartPause.setText("Start");
if (mTimeLeftInMillis < 1000) {
mButtonStartPause.setVisibility(View.INVISIBLE);
} else {
mButtonStartPause.setVisibility(View.VISIBLE);
}
if (mTimeLeftInMillis < START_TIME_IN_MILLIS) {
mButtonReset.setVisibility(View.VISIBLE);
} else {
mButtonReset.setVisibility(View.INVISIBLE);
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("millisLeft", mTimeLeftInMillis);
outState.putBoolean("timerRunning", mTimerRunning);
outState.putLong("endTime", mEndTime);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mTimeLeftInMillis = savedInstanceState.getLong("millisLeft");
mTimerRunning = savedInstanceState.getBoolean("timerRunning");
updateCountDownText();
updateButtons();
if (mTimerRunning) {
mEndTime = savedInstanceState.getLong(enter code here"endTime");
mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
startTimer();
}
}
}
Is there a way to solve this?
You could move the countdown logic and data to a ViewModel
The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations.
It's an architecture component used in the Recommended app architecture.
The MainViewModel code could be:
package com.example.countdown;
import androidx.lifecycle.ViewModel;
public class MainViewModel extends ViewModel {
private static final long START_TIME_IN_MILLIS = 10000;
private boolean mTimerRunning;
private long mTimeLeftInMillis = START_TIME_IN_MILLIS;
private long mEndTime;
boolean getTimerRunning() {
return mTimerRunning;
}
long getTimeLeftInMillis() {
return mTimeLeftInMillis;
}
long getEndTime() {
return mEndTime;
}
void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
mTimerRunning = true;
}
void restoreTimer(boolean timerRunning, long timeLeftInMillis, long endTime) {
this.mTimerRunning = timerRunning;
this.mTimeLeftInMillis = timeLeftInMillis;
this.mEndTime = endTime;
}
void finish() {
mTimerRunning = false;
}
void restart() {
mTimeLeftInMillis = START_TIME_IN_MILLIS;
}
void updateCounter(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
}
boolean remainingTime() {
return mTimeLeftInMillis < START_TIME_IN_MILLIS;
}
}
And the MainActivity:
package com.example.countdown;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
protected MainViewModel viewModel;
private TextView mTextViewCountDown;
private Button mButtonStartPause;
private Button mButtonReset;
private CountDownTimer mCountDownTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewModel = new ViewModelProvider(this).get(MainViewModel.class);
mTextViewCountDown = findViewById(R.id.text_view_countdown);
mButtonStartPause = findViewById(R.id.button_start_pause);
mButtonReset = findViewById(R.id.button_reset);
mButtonStartPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (viewModel.getTimerRunning()) {
pauseTimer();
} else {
startTimer();
}
}
});
mButtonReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
resetTimer();
}
});
updateCountDownText();
}
#Override
protected void onPause() {
super.onPause();
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
}
#Override
protected void onResume() {
super.onResume();
if (viewModel.getTimerRunning()) {
startTimer();
}
}
#Override
protected void onDestroy() {
viewModel.finish();
super.onDestroy();
}
private void startTimer() {
viewModel.startTimer();
mCountDownTimer = new CountDownTimer(viewModel.getTimeLeftInMillis(), 1000) {
#Override
public void onTick(long millisUntilFinished) {
viewModel.updateCounter(millisUntilFinished);
updateCountDownText();
}
#Override
public void onFinish() {
viewModel.finish();
Toast.makeText(MainActivity.this, "Timer finished", Toast.LENGTH_SHORT).show();
updateButtons();
}
}.start();
updateButtons();
}
private void pauseTimer() {
if (mCountDownTimer != null) {
mCountDownTimer.cancel();
}
viewModel.finish();
updateButtons();
}
private void resetTimer() {
viewModel.restart();
updateCountDownText();
updateButtons();
}
private void updateCountDownText() {
int minutes = (int) (viewModel.getTimeLeftInMillis() / 1000) / 60;
int seconds = (int) (viewModel.getTimeLeftInMillis() / 1000) % 60;
String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
mTextViewCountDown.setText(timeLeftFormatted);
}
private void updateButtons() {
if (viewModel.getTimerRunning()) {
mButtonReset.setVisibility(View.INVISIBLE);
mButtonStartPause.setText("Pause");
} else {
mButtonStartPause.setText("Start");
if (viewModel.getTimeLeftInMillis() < 1000) {
mButtonStartPause.setVisibility(View.INVISIBLE);
} else {
mButtonStartPause.setVisibility(View.VISIBLE);
}
if (viewModel.remainingTime()) {
mButtonReset.setVisibility(View.VISIBLE);
} else {
mButtonReset.setVisibility(View.INVISIBLE);
}
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putLong("millisLeft", viewModel.getTimeLeftInMillis());
outState.putBoolean("timerRunning", viewModel.getTimerRunning());
outState.putLong("endTime", viewModel.getEndTime());
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
updateCountDownText();
updateButtons();
long timeLeftInMillis = savedInstanceState.getLong("millisLeft");
if (viewModel.getTimerRunning()) {
timeLeftInMillis = viewModel.getEndTime() - System.currentTimeMillis();
startTimer();
}
viewModel.restoreTimer(savedInstanceState.getBoolean("timerRunning"),
timeLeftInMillis,
savedInstanceState.getLong("endTime"));
}
}
Notice how it gets the ViewModel using ViewModelProvider(), once the activity is recreated it will receive the same ViewModel instance, which is scoped to this activity.
Also, don't forget to destroy the timer in onDestroy(), when this activity is finished and not recreated.

Calculating frequency per minute once timer reaches 0

UPDATE - solution below
I'm new to java (and programming as a whole) and could really use some help.
I'm working on a fragment that includes a timer and counter. The user punches a number into an edit text and hits a "set" button to set the timer to that number in minutes. There's also a frequency counter that increases by 1 each time it's clicked. When the timer reaches zero, I want a "rate" text view to show the result of dividing the number of times the button was clicked by the number of minutes; rate = frequency/minute. For example: If minutes = 5 and frequency = 7, I want the rate text view to display "0.71".
So far, I've gotten the timer and counter to work, but I can't get the rate calculation to work. I keep getting "infinity," which from what I've read means I'm dividing by an integer. What I can't figure out is which number is still an integer. I'm also uncertain that the layout of my code is correct (maybe I'm declaring something where I shouldn't?)
Any help would be greatly appreciated. Thanks in advance!
I've tried using a try/catch statement to avoid dividing by 0.
In XML, I've tried setting the input type to "numberDecimal"
I've tried converting the edit text to an integer and text view to a string before converting to doubles
I've tried converting the edit text and counter directly as doubles.
I've searched stackoverflow, Quora, and YouTube to make sure I'm calculating correctly.
Solution
#Override
public void onFinish() {
mTimerRunning = false;
button_start_pause.setText("Start");
button_start_pause.setVisibility(android.view.View.INVISIBLE);
button_reset.setVisibility(android.view.View.VISIBLE);
text_view_rate.setVisibility(android.view.View.VISIBLE);
calculaterate();
}
}.start();
mTimerRunning = true;
button_start_pause.setText("Pause");
}
public void pauseTimer() {
countDownTimer.cancel();
mTimerRunning = false;
button_start_pause.setText("Start");
updateCountDownText();
}
public void resetTimer() {
if (mTimerRunning) {
countDownTimer.cancel();
mTimeLeftInMillis = (mStartTimeInMillis + 1000);
updateWatchInterface();
startTimer();
} else {
mTimeLeftInMillis = (mStartTimeInMillis);
updateCountDownText();
updateWatchInterface();
button_reset.setVisibility(android.view.View.VISIBLE);
button_start_pause.setVisibility(android.view.View.VISIBLE);
}
}
public void calculaterate() {
double numerator = Double.parseDouble(text_view_frequency.getText().toString());
double denominator = (mStartTimeInMillis/1000)/60;
double rate = (numerator)/(denominator);
DecimalFormat df = new DecimalFormat("#.00");
String ratecalc = df.format(rate);
text_view_rate.setText(ratecalc);
}
Fragment and component IDs
public class fragmentrate extends Fragment {
private EditText edit_text_input;
private TextView text_view_countdown;
private TextView text_view_frequency;
private TextView text_view_rate;
private TextView rate_equals;
private Button button_start_pause;
private Button button_reset;
private Button button_set;
private Button button_frequency;
private Button button_reset_frequency;
private CountDownTimer countDownTimer;
private boolean mTimerRunning;
private long mStartTimeInMillis;
private long mTimeLeftInMillis = mStartTimeInMillis;
private long mEndTime;
private int mCounter;
private double denominator;
View View;
public View onCreateView(#NonNull LayoutInflater inflater, #NonNull ViewGroup container, #NonNull Bundle savedInstanceState) {
View = inflater.inflate(R.layout.rate_fragment, container, false);
text_view_countdown = View.findViewById(R.id.text_view_countdown);
button_start_pause = View.findViewById(R.id.button_start_pause);
button_reset = View.findViewById(R.id.button_reset);
button_frequency = View.findViewById(R.id.button_frequency);
button_reset_frequency = View.findViewById(R.id.button_reset_frequency);
edit_text_input = View.findViewById(R.id.edit_text_input);
button_set = View.findViewById(R.id.button_set);
text_view_frequency = View.findViewById(R.id.text_view_frequency);
text_view_rate = View.findViewById(R.id.text_view_rate);
rate_equals = View.findViewById(R.id.rate_equals);
Frequency counter
button_frequency.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
mCounter ++;
text_view_frequency.setText(Integer.toString(mCounter));
}
});
button_reset_frequency.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
mCounter = 0;
text_view_frequency.setText(Integer.toString(mCounter));
}
});
Timer and rate calculation
button_set.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
String input = edit_text_input.getText().toString();
if (input.length() == 0) {
Toast.makeText(getActivity(), "Please enter a number", Toast.LENGTH_SHORT).show();
return;
}
long millisInput = Long.parseLong(input) * 60000;
if (millisInput == 0) {
Toast.makeText(getActivity(), "Please enter a positive number", Toast.LENGTH_SHORT).show();
return;
}
setTime(millisInput);
edit_text_input.setText("");
}
});
button_start_pause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if (mTimerRunning) {
pauseTimer();
} else {
startTimer();
}
}
});
button_reset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(android.view.View view) {
if(mTimerRunning) {
resetTimer();
} else{
resetTimer();
}
}
});
return View;
}
private void setTime(long milliseconds) {
mStartTimeInMillis = milliseconds;
resetTimer();
}
private void startTimer() {
mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
countDownTimer = new CountDownTimer(mTimeLeftInMillis, 100) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
button_start_pause.setText("Start");
button_start_pause.setVisibility(android.view.View.INVISIBLE);
button_reset.setVisibility(android.view.View.VISIBLE);
try {
double denominator = Integer.parseInt(edit_text_input.getText().toString());
double rate = ((double)mCounter/denominator);
text_view_rate.setText(Double.toString(rate));
}
catch (NumberFormatException e)
{
}
}
}.start();
mTimerRunning = true;
button_start_pause.setText("Pause");
}
private void pauseTimer() {
countDownTimer.cancel();
mTimerRunning = false;
updateCountDownText();
button_start_pause.setText("Start");
}
private void resetTimer() {
if (mTimerRunning) {
countDownTimer.cancel();
mTimeLeftInMillis = (mStartTimeInMillis + 1000);
updateWatchInterface();
startTimer();
} else {
}
mTimeLeftInMillis = (mStartTimeInMillis);
updateCountDownText();
updateWatchInterface();
button_reset.setVisibility(android.view.View.VISIBLE);
button_start_pause.setVisibility(android.view.View.VISIBLE);
}
private void updateCountDownText() {
int minutes = (int) (mTimeLeftInMillis/1000)/60;
int seconds = (int) (mTimeLeftInMillis/1000)%60;
String timeLeftFormatted = String.format(Locale.getDefault(),
timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds));
text_view_countdown.setText(timeLeftFormatted);
}
I expect the output of 5/7 to be 0.71, but the actual output is "Infinity"

CountDownTimer is not stopping on BackPressed running in background,may be handler.postDelayed() is the issue. How to fix it in this code?

My Countdown timer is working fine but when I use back press during running state of the time, my countdown timer did not stop. I have tried everything as follows but none of them is able to stop the countdown timer from running in the background. After searching the forum an applying the results from it to my project I am unable to figure out whats fault in my code. Please anyone help me out and I shall be very thankful.
public class QuizActivity extends AppCompatActivity {
private static final long COUNTDOWN_IN_MILLIS = 30000 ;
List<Questions> mQuestions;
int score = 0;
int qid = 0;
Questions currentQ;
TextView txtQuestions, textViewCountDown;
RadioButton rda, rdb, rdc;
Button btnNext;
private QuestionsViewModel questionsViewModel;
private RelativeLayout relativeLayout;
private LinearLayout linearLayout;
private ColorStateList textColorDefaultCd;
private CountDownTimer countDownTimer;
private long timeLeftInMillis;
private Handler handler;
private Runnable runnable = new Runnable() {
#Override
public void run() {
takeAction();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
textViewCountDown = findViewById(R.id.text_view_countdown);
relativeLayout = (RelativeLayout)findViewById(R.id.profileLoadingScreen);
linearLayout = (LinearLayout) findViewById(R.id.linearView);
textColorDefaultCd = textViewCountDown.getTextColors();
fetchQuestions();
questionsViewModel = ViewModelProviders.of(QuizActivity.this).get(QuestionsViewModel.class);
questionsViewModel.getAllQuestions().observe(this, new Observer<List<Questions>>() {
#Override
public void onChanged(#Nullable final List<Questions> words) {
// Update the cached copy of the words in the adapter.
mQuestions = words;
//Collections.shuffle(mQuestions);
Collections.addAll(mQuestions);
}
});
}
private void fetchQuestions() {
DataServiceGenerator dataServiceGenerator = new DataServiceGenerator();
Service service = DataServiceGenerator.createService(Service.class);
Call<List<QuestionsModel>> call = service.getQuestions();
call.enqueue(new Callback<List<QuestionsModel>>() {
#Override
public void onResponse(Call<List<QuestionsModel>> call, Response<List<QuestionsModel>> response) {
if (response.isSuccessful()){
if (response != null){
List<QuestionsModel> questionsModelList = response.body();
for (int i = 0; i < questionsModelList.size(); i++){
String question = questionsModelList.get(i).getQuestion();
String answer = questionsModelList.get(i).getAnswer();
String opta = questionsModelList.get(i).getOpta();
String optb = questionsModelList.get(i).getOptb();
String optc = questionsModelList.get(i).getOptc();
Questions questions = new Questions(question, answer, opta, optb, optc);
questionsViewModel.insert(questions);
}
handler = new Handler();//add this
handler.postDelayed(runnable,3000);
/* Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
takeAction();
}
}, 3000); */
}
}else{
}
}
#Override
public void onFailure(Call<List<QuestionsModel>> call, Throwable t) {
}
});
}
private void setQuestionView()
{
txtQuestions.setText(currentQ.getQuestion());
rda.setText(currentQ.getOptA());
rdb.setText(currentQ.getOptB());
rdc.setText(currentQ.getOptC());
qid++;
}
private void startCountDown() {
countDownTimer = new CountDownTimer(timeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
timeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
timeLeftInMillis = 0;
updateCountDownText();
Intent intent = new Intent(QuizActivity.this, ResultActivity.class);
Bundle b = new Bundle();
b.putInt("score", score); //Your score
intent.putExtras(b); //Put your score to your next Intent
startActivity(intent);
finish();
}
}.start();
}
private void updateCountDownText() {
int minutes = (int) (timeLeftInMillis / 1000) / 60;
int seconds = (int) (timeLeftInMillis / 1000) % 60;
String timeFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
textViewCountDown.setText(timeFormatted);
if (timeLeftInMillis < 10000) {
textViewCountDown.setTextColor(Color.RED);
} else {
textViewCountDown.setTextColor(textColorDefaultCd);
}
}
private void takeAction() {
relativeLayout.setVisibility(View.GONE);
linearLayout.setVisibility(View.VISIBLE);
textViewCountDown.setVisibility(View.VISIBLE);
timeLeftInMillis = COUNTDOWN_IN_MILLIS;
startCountDown();
currentQ = mQuestions.get(qid);
txtQuestions = (TextView)findViewById(R.id.textView1);
rda=(RadioButton)findViewById(R.id.radio0);
rdb=(RadioButton)findViewById(R.id.radio1);
rdc=(RadioButton)findViewById(R.id.radio2);
btnNext=(Button)findViewById(R.id.button1);
setQuestionView();
btnNext.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RadioGroup grp=(RadioGroup)findViewById(R.id.radioGroup1);
if (grp.getCheckedRadioButtonId() == -1){
Toast.makeText(getApplicationContext(),
"Please Select an Answer",
Toast.LENGTH_SHORT)
.show();
return;
}else{
// countDownTimer.cancel();
}
RadioButton answer=(RadioButton)findViewById(grp.getCheckedRadioButtonId());
grp.clearCheck();
//Log.d("yourans", currentQ.getANSWER()+" "+answer.getText());
if(currentQ.getAnswer().equals(answer.getText()))
{
score++;
Log.d("score", "Your score"+score);
}else{
}
if(qid<10){
currentQ=mQuestions.get(qid);
setQuestionView();
}else{
Intent intent = new Intent(QuizActivity.this, ResultActivity.class);
Bundle b = new Bundle();
b.putInt("score", score); //Your score
intent.putExtras(b); //Put your score to your next Intent
startActivity(intent);
finish();
}
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
if(handler!=null){
handler.removeCallbacks(runnable);
}
if (countDownTimer != null) {
countDownTimer.cancel();
countDownTimer = null;
}
finish();
}
#Override
protected void onPause() {
super.onPause();
if(handler!=null){
handler.removeCallbacks(runnable);
}
if (countDownTimer!=null) {
countDownTimer.cancel();
countDownTimer = null;
}
finish();
}
#Override
protected void onStop() {
super.onStop();
if(handler!=null){
handler.removeCallbacks(runnable);
}
if (countDownTimer!=null) {
countDownTimer.cancel();
countDownTimer = null;
}
finish();
}
#Override
public void onBackPressed() {
if (countDownTimer!=null) {
countDownTimer.cancel();
countDownTimer = null;
}
finish();
}
}
Try this code
#Override
public void onBackPressed() {
if(handler!=null){
handler.removeCallbacks(runnable);
}
if (countDownTimer!=null) {
countDownTimer.cancel();
countDownTimer = null;
}
finish();
}

Unable to set timer in Snackbar

I am trying to set a timer in my Snackbar, I have tried this so far and gotten the timer to work but not in the getTime() method which I think might be the case which is why this isn't working.
I am sorry if this is too bad of a question, I only do Android as a side project.
public class MainActivity extends AppCompatActivity {
private static final String AUDIO_RECORDER_FILE_EXT = ".3gp";
private static final String AUDIO_RECORDER_FOLDER = "VRemind";
private MediaRecorder recorder = null;
private int currentFormat = 0;
private int output_format = MediaRecorder.OutputFormat.THREE_GPP;
private String file_ext = AUDIO_RECORDER_FILE_EXT;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final CountDownTimer t;
t = new CountDownTimer( Long.MAX_VALUE , 1000) {
int cnt=0;
#Override
public void onTick(long millisUntilFinished) {
cnt++;
long millis = cnt;
int seconds = (int) (millis / 60);
setTime(cnt);
Log.d("Count:", ""+cnt);
}
#Override
public void onFinish() {
}
};
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final Snackbar snackbar = Snackbar.make(findViewById(R.id.root_layout), getTime(), Snackbar.LENGTH_INDEFINITE);
final FloatingActionButton fabAdd = (FloatingActionButton) findViewById(R.id.fabAdd);
final FloatingActionButton fabStop = (FloatingActionButton) findViewById(R.id.fabStop);
fabAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.start();
fabAdd.setVisibility(View.GONE);
fabStop.setVisibility(View.VISIBLE);
snackbar.show();
snackbar.setAction("CANCEL", new View.OnClickListener() {
#Override
public void onClick(View v) {
snackbar.dismiss();
fabAdd.setVisibility(View.VISIBLE);
fabStop.setVisibility(View.GONE);
}
});
}
});
fabStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.cancel();
snackbar.dismiss();
fabStop.setVisibility(View.GONE);
fabAdd.setVisibility(View.VISIBLE);
}
});
}
private String display;
public void setTime(int rawCount) {
int rc = rawCount;
int minutes = (rc - (rc % 60)) / 60;
int seconds = (rc % 60);
String mins = String.format(Locale.ENGLISH, "%02d", minutes);
String secs = String.format(Locale.ENGLISH, "%02d", seconds);
display = mins+ ":" +secs;
Log.d("CountTwo:",display);
getTime();
}
public String getTime() {
Log.d("Count getTime:", display);
return display;
}
Are you getting this message?
java.lang.NullPointerException: println needs a message
If yes it is because you try to log a null message like this:
Log.d("Count getTime:", display);
You have to initialize the display variable to have a value for the first run.
private String display = "";
I looked into it and the problem was that the String display was inaccessible to the Snackbar and also the Snackbar test was unable to update dynamically so I did both of those and made a few changes here and there and here's my code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final CountDownTimer t;
t = new CountDownTimer( Long.MAX_VALUE , 1000) {
int cnt=0;
#Override
public void onTick(long millisUntilFinished) {
cnt++;
long millis = cnt;
int seconds = (int) (millis / 60);
setTime(cnt);
Log.d("Count:", ""+cnt);
}
#Override
public void onFinish() {
cnt = 0;
}
};
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
snackbar = Snackbar.make(findViewById(R.id.root_layout), "", Snackbar.LENGTH_INDEFINITE);
final FloatingActionButton fabAdd = (FloatingActionButton) findViewById(R.id.fabAdd);
final FloatingActionButton fabStop = (FloatingActionButton) findViewById(R.id.fabStop);
fabAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.start();
fabAdd.setVisibility(View.GONE);
fabStop.setVisibility(View.VISIBLE);
snackbar.show();
snackbar.setAction("CANCEL", new View.OnClickListener() {
#Override
public void onClick(View v) {
t.cancel();
t.onFinish();
// setTime(0);
snackbar.dismiss();
fabAdd.setVisibility(View.VISIBLE);
fabStop.setVisibility(View.GONE);
}
});
}
});
fabStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
t.cancel();
t.onFinish();
// setTime(0);
snackbar.dismiss();
fabStop.setVisibility(View.GONE);
fabAdd.setVisibility(View.VISIBLE);
}
});
}
/*
public void Duration() {
*//* Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
int count;
#Override
public void run() {
setTime(count);
count++;
Log.d("Count:", ""+count);
}
});
}
};*//* //Old code removed on 22Apr17#11:41PM
}*/ //Old code Duration method
String display="";
public void setTime(int rawCount) {
// int rc = rawCount;
int minutes = (rawCount - (rawCount % 60)) / 60;
int seconds = (rawCount % 60);
String mins = String.format(Locale.ENGLISH, "%02d", minutes);
String secs = String.format(Locale.ENGLISH, "%02d", seconds);
display = mins+ ":" +secs;
Log.d("CountTwo:",display);
snackbar.setText(display);
}
/*public String getTime() {
Log.d("Count getTime:", display);
return display;
}*/

Categories

Resources