Here I have made this method for starting my timer and the one below it updates the timer:
private void startTimer()
{
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
progress++;
pb.setProgress((int)progress*100/((int)millisUntilFinished/1000));
}
#Override
public void onFinish()
{
progress++;
pb.setProgress(100);
//Vibration
if (Build.VERSION.SDK_INT >= 26)
{
((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(VibrationEffect.createOneShot(150, VibrationEffect.DEFAULT_AMPLITUDE));
Toast.makeText(MainActivity2.this,"Done",Toast.LENGTH_SHORT).show();
}
else
{
((Vibrator) getSystemService(VIBRATOR_SERVICE)).vibrate(VibrationEffect.createWaveform(new long[]{150}, new int[]{VibrationEffect.EFFECT_CLICK},-1));
}
}
}.start();
}
private void updateCountDownText()
{
//time in minutes and seconds
int minutes = (int)(mTimeLeftInMillis/1000)/60;
int seconds = (int)(mTimeLeftInMillis/1000)%60;
//formating the above to appear as String
String timeLeftFormatted = String.format("%02d:%02d",minutes,seconds);
timer.setText(timeLeftFormatted);
}
"pb" is the name of my progressbar. It keeps finishing earlier than the countdown by 2 minutes and I don't know how to synchronize them. Also upon completion the vibration is not triggered for some reason even though it did before. "progress" is initialized as zero as a global variable.
Here is the solution:
long millisInFuture;
private void startTimer() {
millisInFuture = mTimeLeftInMillis;
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
long millisPassed = millisInFuture - mTimeLeftInMillis;
progress = (int) (millisPassed * 100 / millisInFuture);
pb.setProgress(progress);
}
#Override
public void onFinish() {
pb.setProgress(100);
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
VibrationEffect effect =
VibrationEffect.createOneShot(150, VibrationEffect.DEFAULT_AMPLITUDE);
vibrator.vibrate(effect);
Toast.makeText(MainActivity2.this, "Done", Toast.LENGTH_SHORT).show();
} else {
vibrator.vibrate(150);
}
}
}.start();
}
But I don't see when you initialize your progressbar.
If you set pb.max ( or setMax in Java ) = 100
And on each onTick call a method :
private changePb(long millisUntilFinished){
pb.progress = (millisUntilFinished / millisStartValue) * 100
}
Where millisStartValue was the first value you put in new CountDownTimer(mTimeLeftInMillis
And in onFinish, you don't have to put new value for progressbar.
Related
Picture Reference
I need help adding one more minute using the on click button in Android Studio
Here's some of my timer code:
private void startTimer() {
mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
#Override
public void onTick(long millisUntilFinished) {
mTimeLeftInMillis = millisUntilFinished;
updateCountDownText();
}
#Override
public void onFinish() {
mTimerRunning = false;
btnTest.setText("Start");
}
}.start();
mTimerRunning = true;
btnTest.setText("Pause");
}
private void pauseTimer() {
mCountDownTimer.cancel();
mTimerRunning = false;
btnTest.setText("Start");
}
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);
textViewShowTime.setText(timeLeftFormatted);
mProgressBar.setProgress((int)(mTimeLeftInMillis / 1000));
}
Unfortunately, this class does not have such a feature.
you can save the count of the button click, then create a new CountDownTimer with the timeout that you want. and you need to consider the remaining time in the onTick method.
You can create CustomCountDowntimer that extends from CountDownTimer. And do the things described above there.
see this link
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);
}
I'm trying to use variable into the CountDownTimer constructor but the application doesn't work. Normally works with duration without a variable(like 10000). How Can I use a variable?
my code
private CountDownTimer countDownTimer = new CountDownTimer(duration, 1000) {
#Override
public void onTick(long l) {
txt_count.setText(String.valueOf(l / 1000));
progressBar.setProgress((int) l/ 1000);
}
#Override
public void onFinish() {
iscountering = false;
if(temp_question.getQuestions().size() !=(temp_position+1))
Do_Next_Question(temp_position,temp_question);
else
Toast.makeText(ObserverRoomActivity.this, "پایان آزمون", Toast.LENGTH_SHORT).show()
}
};
private void StartTimer(){
if(!iscountering){
iscountering = true;
countDownTimer.start();
}else{
iscountering = false;
countDownTimer.cancel();
}
}
I think you need to use timer like this:
private CountDownTimer countDownTimer;
private void createTimer(int duration) {
countDownTimer = new CountDownTimer(duration, 1000) {
#Override
public void onTick(long l) {
txt_count.setText(String.valueOf(l / 1000));
progressBar.setProgress((int) l/ 1000);
}
#Override
public void onFinish() {
iscountering = false;
if(temp_question.getQuestions().size() !=(temp_position+1))
Do_Next_Question(temp_position,temp_question);
else
Toast.makeText(ObserverRoomActivity.this, "پایان آزمون", Toast.LENGTH_SHORT).show()
}
};
}
private void StartTimer(){
if(!iscountering){
iscountering = true;
countDownTimer.start();
} else {
iscountering = false;
countDownTimer.cancel();
}
}
// Call this method to pass your duration for the timer
private void createAndStartTimer(int duration) {
createTimer(duration);
startTimer();
}
I am making a chess clock but in it I need a delay (Like it waits 10 seconds before counting). I used a Handler for it but if the button is clicked in the 10 seconds, nothing happens. Please help! Thanks!
My code:
mHandler.postDelayed(new Runnable() {
public void run() {
// count down timer start
timer2 = new CountDownTimer(totalSeconds, Integer.parseInt(delay.getText().toString())) {
public void onTick(long millisUntilFinished) {
secondsTimer = (int) (millisUntilFinished / 1000) % 60;
minutesTimer = (int) ((millisUntilFinished / (1000 * 60)) % 60);
hoursTimer = (int) ((millisUntilFinished / (1000 * 60 * 60)) % 24);
person2.setText(hoursTimer + ":" + minutesTimer + ":" + secondsTimer);
}
public void onFinish() {
person2.setText("Time Up!");
person2.setBackgroundColor(Color.RED);
mp.start();
}
}.start();
}
}, finalDelay);
I want a delay but I don't want to lock the UI and make the app unresponsive as it is doing right now with the handler. Any help will be appreciated! Thanks in advance!
I think you shouldn't put CountdownTimer into Handler. You could create 2 handler instead. Here is an example.
private void startHandlerAndWait10Seconds(){
Handler handler1 = new Handler();
handler1.postDelayed(new Runnable() {
public void run() {
// Start Countdown timer after wait for 10 seconds
startCountDown();
}
}, 10000);
}
private void startCountDown {
final Handler handler2 = new Handler();
handler2.post(new Runnable() {
int seconds = 60;
public void run() {
seconds--;
mhello.setText("" + seconds);
if (seconds < 0) {
// DO SOMETHING WHEN TIMES UP
stopTimer = true;
}
if(stopTimer == false) {
handler2.postDelayed(this, 1000);
}
}
});
}
If you want to start the timer immediately,
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Handler().post(new Runnable() {
public void run() {
// count down timer start
new CountDownTimer(100000, 1000) {
public void onTick(long millisUntilFinished) {
button.setText(String.valueOf(millisUntilFinished));
}
public void onFinish() {
button.setText("Time Up!");
}
}.start();
}
});
}
});
And if you want to execute it after a certain time period, then
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Handler().postDelayed(new Runnable() {
public void run() {
// count down timer start
new CountDownTimer(100000, 1000) {
public void onTick(long millisUntilFinished) {
button.setText(String.valueOf(millisUntilFinished));
}
public void onFinish() {
button.setText("Time Up!");
}
}.start();
}
}, 1000);
}
});
You can avoid using Handler starting timer immediately
private fun start10SecondsDelayTimer() {
var delayCount = 10
val timer = object : CountDownTimer(1_000_000L, 1000L) {
override fun onTick(millisUntilFinished: Long) {
if (delayCount > 0) {
delayCount--
} else {
//your calculations
}
}
override fun onFinish() {
//some calculations
}
}
timer.start()
}
but first ticks will be without your calculations
I am trying to start a timer when activity created and be able to reset the timer back from zero if the same button is pressed but every time I press the button that initiates the set Interval it seems to be creating a new interval and not resetting the one that was already creating. Can someone help please? Here is my code
timer = (TextView) findViewById(R.id.timer_value);
Count = new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("OUT OF TIME!");
if (time < 10000) {
time = 10000;
}
AlertDialog.Builder builder = new AlertDialog.Builder(
TicTacToe.this);
builder.setMessage("You are Out of Time").setPositiveButton(
"Replay", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// reset the game environment.
Count.onFinish();
// Count.cancel();
Count.start();
new_game(player_name_1);
}
});
AlertDialog alert = builder.create();
alert.show();
}
}.start();
you can use timers
//in global
Timer myTimer
/**
* its kills runnable
*/
public void stopTimer(){
//handler.removeCallbacks(null); //it resets all timer which handler holds
myTimer.cancel();
}
public void setTimer(int time){//give it 5 for 5 secs
final Runnable Update = new Runnable() {
public void run() {
//do sth
}
};
myTimer = new Timer();
myTimerTimer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(Update);
}
}, 1000, time*1000);
}
If you want to restart your timer, remove Count.onFinish();
Update:
I replaced AlertDialog with a new thread and here is the code that works on my emulator
public class MainActivity extends Activity
{
int time = 10000;
CountDownTimer Count;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView timer = (TextView) findViewById(R.id.timer);
Count = new CountDownTimer(time, 1000) {
public void onTick(long millisUntilFinished) {
timer.setText("Time Left: " + millisUntilFinished / 1000);
}
public void onFinish() {
timer.setText("OUT OF TIME!");
if (time < 10000) {
time = 100000;
}
}
}.start();
}
public void buttonClicked(View view)
{
Log.i("Timer", "Resetting timer");
Count.cancel();
Count.start();
}
}