Count Down Timer for a timer - java

I am trying to make a Pomodoro Timer (25 minutes work, 5 minutes break then repeat n times). But I can't find a way to let the break timer start automatically and then start again with the work timer (work timer = 00:10 - break timer = 00:03, i put these values so i can test faster). How can I fix this?
public class MainActivity extends AppCompatActivity {
TextView tvTimer, tvSessions;
ImageView ivStart, ivStop;
SeekBar seekBar;
CountDownTimer countDownTimer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTimer = findViewById(R.id.tvTimer);
tvSessions = findViewById(R.id.tvSessions);
ivStart = findViewById(R.id.ivStart);
ivStop = findViewById(R.id.ivStop);
seekBar = findViewById(R.id.seekBar);
seekBar.setMax(2500);
seekBar.setProgress(10);
seekBar.setVisibility(View.GONE);
tvTimer.setText("00:10");
}
// ON CLICK METHODS
public void startTimer(View v){
countDownTimer = new CountDownTimer(seekBar.getProgress() * 1000 + 100, 1000) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
breakTimer();
}
};
countDownTimer.start();
}
public void stopTimer(View v){
}
// UPDATE METHODS
private void breakTimer(){
seekBar.setProgress(3);
tvTimer.setText("00:03");
}
private void updateTimer(int progress){
int minutes = progress / 60;
int seconds = progress - minutes * 60;
String textMinutes = String.valueOf(minutes);
String textSeconds = String.valueOf(seconds);
if(seconds < 10) textSeconds = "0" + textSeconds;
if(minutes < 10) textMinutes = "0" + textMinutes;
tvTimer.setText(textMinutes + ":" + textSeconds);
}
}
Expected output:
00:10 -> 00:00 -> 00:03 -> 00:00 -> 00:10 and so on...

What about something like this. Using a flag to keep track of if the Timer is a rest timer or a pomodoro timer.
When the timer finishes, you check the flag to decide which timer to start next (and flip the flag so next time it does the opposite).
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
private static final int TICK_EVERY_SECOND = 1000;
private TextView tvTimer, tvSessions;
private ImageView ivStart, ivStop;
private SeekBar seekBar;
private CountDownTimer countDownTimer;
private boolean isRest = false;
private int userSelectedDurationSeconds = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTimer = findViewById(R.id.tvTimer);
tvSessions = findViewById(R.id.tvSessions);
ivStart = findViewById(R.id.ivStart);
ivStop = findViewById(R.id.ivStop);
seekBar = findViewById(R.id.seekBar);
seekBar.setMax(2500);
seekBar.setProgress(10);
seekBar.setVisibility(View.GONE);
tvTimer.setText("00:10");
}
// ON CLICK METHODS
public void startTimer(View v) {
isRest = false;
int durationSeconds = seekBar.getProgress();
userSelectedDurationSeconds = durationSeconds;
restartTimer(durationSeconds);
}
private void restartTimer(int durationSeconds) {
countDownTimer = new CountDownTimer(TimeUnit.SECONDS.toMillis(durationSeconds), TICK_EVERY_SECOND) {
#Override
public void onTick(long millisUntilFinished) {
updateTimer((int) millisUntilFinished / 1000);
}
#Override
public void onFinish() {
breakTimer();
}
};
countDownTimer.start();
}
public void stopTimer(View v) {
}
// UPDATE METHODS
private void breakTimer() {
isRest = !isRest;
if(isRest) {
seekBar.setProgress(3);
tvTimer.setText("00:03");
restartTimer(3);
} else {
restartTimer(userSelectedDurationSeconds);
}
}
private void updateTimer(int progressInSeconds) {
int minutes = progressInSeconds / 60;
int seconds = progressInSeconds - minutes * 60;
String textMinutes = String.valueOf(minutes);
String textSeconds = String.valueOf(seconds);
if (seconds < 10) textSeconds = "0" + textSeconds;
if (minutes < 10) textMinutes = "0" + textMinutes;
tvTimer.setText(textMinutes + ":" + textSeconds);
}
}

Related

How to calculate the current millisecond provided if there is old millisecond in java

I making a timer in my android app. I have a scenario where I dont need to stop the timer even if the app is closed. If the timer is running and user closes the app and reopen it after sometime. He should see the latest time on the timer. But currently I am not able to show the latest time. I am only able to show the time when the user killed the app. I am storing the time of the timer and when the user open the app I am putting the stored time back to the timer. But I want to show the latest time. Here what I have done till now. I am using chronometer widget.
MainActivity.class:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = MainActivity.class.getSimpleName();
Chronometer tvTextView;
Button btnStart, btnStop;
private int state = 0; //0 means stop state,1 means play, 2 means pause
SharedPreferences sharedPreferences;
private boolean running = false;
private long pauseOffSet = -1;
ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvTextView = findViewById(R.id.textview);
progressBar = findViewById(R.id.puzzleProgressBar);
btnStart = findViewById(R.id.button1);
btnStop = findViewById(R.id.button2);
btnStart.setOnClickListener(this);
btnStop.setOnClickListener(this);
sharedPreferences = getSharedPreferences("myprefs", MODE_PRIVATE);
state = sharedPreferences.getInt("state", 0);
tvTextView.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
long time = SystemClock.elapsedRealtime() - chronometer.getBase();
pauseOffSet=time;
Log.e(TAG,"pauseOffSet "+pauseOffSet);
if (time >= 79200000) {
tvTextView.setBase(SystemClock.elapsedRealtime());
tvTextView.stop();
running = false;
progressBar.setProgress(0);
} else {
chronometer.setText(setFormat(time));
int convertTime = (int) time;
progressBar.setProgress(convertTime);
}
}
});
if (state == 1) { // its in play mode
running = true;
tvTextView.setBase(SystemClock.elapsedRealtime() - sharedPreferences.getLong("milli", 0));
tvTextView.start();
} else if (state == 2) { //its in pause mode
running = false;
pauseOffSet = sharedPreferences.getLong("milli", -1);
long time = SystemClock.elapsedRealtime() - pauseOffSet;
tvTextView.setBase(time);
int convertTime = (int) pauseOffSet;
progressBar.setProgress(convertTime);
} else {
running = false;
tvTextView.setBase(SystemClock.elapsedRealtime());
}
}
public void onClick(View v) {
if (btnStart == v) {
if (!running) {
if (pauseOffSet != -1) {
pauseOffSet = sharedPreferences.getLong("milli", -1);
}
tvTextView.setBase(SystemClock.elapsedRealtime() - pauseOffSet);
tvTextView.start();
state = 1;
pauseOffSet = 0;
running = true;
}
} else if (btnStop == v) {
if (running) {
tvTextView.stop();
pauseOffSet = SystemClock.elapsedRealtime() - tvTextView.getBase();
state = 2;
running = false;
}
}
}
#Override
protected void onStop() {
super.onStop();
sharedPreferences.edit().putLong("milli", pauseOffSet).commit();
sharedPreferences.edit().putInt("state", state).commit();
}
#Override
protected void onDestroy() {
Log.e(TAG, "onDestroy called, state: " + state);
super.onDestroy();
}
String setFormat(long time) {
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
String hh = h < 10 ? "0" + h : h + "";
String mm = m < 10 ? "0" + m : m + "";
String ss = s < 10 ? "0" + s : s + "";
return hh + ":" + mm + ":" + ss;
}
}

Android: Double Value dissappears inside textbox

A simple countdowntimer that updates the value of a double variable and then display the value onto the end of a textbox. I have done this with integers and it works fine, however when I use a double value it just simply disappears from the end of the textbox. Is there a reason for this occurance?
Code used:
PSICount = new CountDownTimer(5000,1000) {
#Override
public void onTick(long millisUntilFinished) {
timer2.setText("seconds remaining: " + millisUntilFinished / 1000);
}
#Override
public void onFinish() {
if(alti >= 33000){
Random r = new Random();
double Low = 0.2 ;
double High = 0.5;
double randomValue = Low + (High - Low) * r.nextDouble();
pressure = pressure - randomValue;
pressureT.setText("Pressure: "+ pressure + " PSI");
}
PSICount.start();
}
};
PSICount.start();
This is the timer and it triggers every 5 seconds if the value of another variable is above 33000. As soon as that variable reaches 33000, the textbox (which has a placeholder value of 10.0 at the end) does not display any value at the end. Do I need to do something to use doubles with textViews?
Thank you
My entire Class:
import android.content.pm.ActivityInfo;
import android.graphics.Typeface;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.Random;
public class flight_engineer extends AppCompatActivity {
int fuel = 100;
int alti = 10000;
int speed = 50;
double over_heat = 600;
double pressure = 10.0;
CountDownTimer fuelCount;
CountDownTimer PSICount;
CountDownTimer spike;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flight_engineer);
//sets screen orientation on created
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
Typeface typeface = Typeface.createFromAsset(getAssets(), "Stencil WW.ttf");
final TextView fuelT = (TextView) findViewById(R.id.fuelText);
final TextView pressureT = (TextView) findViewById(R.id.presText);
final TextView altitudeT = (TextView) findViewById(R.id.altText);
final TextView speedT = (TextView) findViewById(R.id.speedText);
final TextView over_heatingT = (TextView) findViewById(R.id.heatText);
final TextView info = (TextView) findViewById(R.id.infoText);
final TextView timer = (TextView) findViewById(R.id.timer);
final TextView timer2 = (TextView) findViewById(R.id.timer2);
fuelT.setTypeface (typeface);
pressureT.setTypeface (typeface);
altitudeT.setTypeface (typeface);
speedT.setTypeface (typeface);
over_heatingT.setTypeface (typeface);
info.setTypeface(typeface);
fuelT.setText("Fuel: "+fuel);
pressureT.setText("Pressure: "+ pressure+ " PSI");
altitudeT.setText("Altitude: "+alti+" ft");
speedT.setText("Speed: "+speed+" MPH");
over_heatingT.setText("System Heat: "+over_heat+" °C");
Button speedPlus = (Button) findViewById(R.id.speedPlus);
speedPlus.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
fuelCount = new CountDownTimer(2000,1000) {
#Override
public void onTick(long millisUntilFinished) {
timer.setText("seconds remaining: " + millisUntilFinished / 1000);
}
#Override
public void onFinish() {
fuelCount.start();
fuel--;
fuelT.setText("Fuel: "+fuel);
over_heat=over_heat + 4;
fuelT.setText("Fuel: "+fuel);
over_heatingT.setText("System Heat: "+over_heat+" °C");
Random r = new Random();
int Low = 443;
int High = 872;
int Result = r.nextInt(High - Low) + Low;
alti = alti + Result;
altitudeT.setText("Altitude: "+alti+" ft");
}
};
fuelCount.start();
PSICount = new CountDownTimer(5000,1000) {
#Override
public void onTick(long millisUntilFinished) {
timer2.setText("seconds remaining: " + millisUntilFinished / 1000);
}
#Override
public void onFinish() {
if(alti >= 33000){
Random r = new Random();
double Low = 0.2 ;
double High = 0.5;
double randomValue = Low + (High - Low) * r.nextDouble();
pressure = pressure - randomValue;
pressureT.setText("Pressure: "+ pressure + " PSI");
}
PSICount.start();
}
};
PSICount.start();
spike = new CountDownTimer(30000,1000) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
spike.start();
over_heat = over_heat + 50;
over_heatingT.setText("System Heat: "+over_heat+" °C");
alti = alti + 1000;
altitudeT.setText("Altitude: "+alti+" ft");
if(speed < 300 || speed > 300) {
Random r = new Random();
int Low = -50;
int High = 50;
int Result = r.nextInt(High - Low) + Low;
speed = speed + Result;
speedT.setText("Speed: " + speed + " MPH");
}
}
};
spike.start();
}
}

Android CountDownTimer - adding time results in multiple timers running

Im trying to make it so that my timer adds 5 seconds every time I press the button. I've learnt that I need to cancel the previous timer and create a new one for it to work the way I want it to. When I press the button once, the timer adds 5 seconds and everything works fine as its supposed to. My problem arises when I press the button multiple times. The timer will flicker between many different timers instead of staying on the latest one. Every time I press the button, another timer is flickering on the display. Its almost as if the program doesnt cancel the previous timers and just creates a new every time. I'd really appreciate some help on this. Thanks guys!
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
int scoreTeamA = 0;
String countDownTimer;
long millisUntilFinishedInt = 5000;
long milliseconds;
long seconds;
long totalAddedTime = 0;
TextView text1;
MyCount counter = new MyCount(millisUntilFinishedInt + totalAddedTime,17);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text1=(TextView)findViewById(R.id.team_a_score);
counter.start();
}
public class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
millisUntilFinishedInt = millisUntilFinished;
seconds = millisUntilFinishedInt/1000;
milliseconds = millisUntilFinishedInt-(millisUntilFinishedInt/1000)*1000;
countDownTimer = "TIME: " + seconds + "." + milliseconds ;
text1.setText(countDownTimer);
}
#Override
public void onFinish() {
countDownTimer = "TIME'S UP!";
text1.setText(countDownTimer);
}
}
public void timerCreation (){
counter.cancel();
MyCount counter = new MyCount(millisUntilFinishedInt + 5000,1);
counter.start();
}
//method that is called when button is pressed
public void threePoints (View v) {
timerCreation();
}
}
Change this
public void timerCreation (){
counter.cancel();
MyCount counter = new MyCount(millisUntilFinishedInt + 5000,1);
counter.start();
}
Into this
public void timerCreation (){
counter.cancel();
counter = new MyCount(millisUntilFinishedInt + 5000,1);
counter.start();
}
With your current implementation, you are cancelling your member variable counter. Then you create a local variable with the same name and start that one. The next time you press your button, your member variable counter gets cancelled again (which is already cancelled) in order to create a new MyCount object and start that one. That is why you are ending up with multiple timers
Changes: increase interal to 50 but but mandatory.
MyCount counter = new MyCount(millisUntilFinishedInt + totalAddedTime, 50);
Align text view gravity to left android:gravity="left" so user cant feel its new timmer.
Tested Working Demo
MainActivity
public class MainActivity extends AppCompatActivity {
Context context;
int scoreTeamA = 0;
String countDownTimer;
long millisUntilFinishedInt = 5000;
long milliseconds;
long seconds;
long totalAddedTime = 0;
TextView text1;
MyCount counter = new MyCount(millisUntilFinishedInt + totalAddedTime, 50);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
text1 = (TextView) findViewById(R.id.foodName);
text1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
timerCreation();
}
});
}
public class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
millisUntilFinishedInt = millisUntilFinished;
seconds = millisUntilFinishedInt / 1000;
milliseconds = millisUntilFinishedInt - (millisUntilFinishedInt / 1000) * 1000;
countDownTimer = "TIME: " + seconds + "." + milliseconds;
text1.setText(countDownTimer);
}
#Override
public void onFinish() {
countDownTimer = "TIME'S UP!";
text1.setText(countDownTimer);
}
}
public void timerCreation() {
counter.cancel();
MyCount counter = new MyCount(millisUntilFinishedInt + 5000, 1);
counter.start();
}
//method that is called when button is pressed
public void threePoints(View v) {
timerCreation();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/base"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#color/white"
android:orientation="horizontal"
android:weightSum="10">
<TextView
android:id="#+id/foodName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:hint="Food name"
android:gravity="left"
android:inputType="textCapWords"
android:textColor="#color/colorPrimaryDark"
android:textColorHint="#color/colorPrimaryDark"
android:textSize="32sp"
android:layout_marginLeft="20dp" />
</RelativeLayout>

Stopwatch repeating time one after another with pause between

this is my first time writing here. I am learning Android development and trying to make a stopwatch (countdown timer) app, which has 12 rounds and pause - example 10 sec between them. I wrote a code which works fine but I want to write it more "readable and nicely" so I would like to ask you for your help. As you can see, I don't want to write every time under public void run() in if-else if statement new roundtime number and setting text because it would take too much space. That is why I wrote it just for example(not 12 times) so you can see what I mean. Do you have any suggestions how to write it better for 12 rounds? Can I use a loop? If u have easier way for countdown round after round I would appreciate it. I am sorry for my english. Any comments are welcome. Enjoy coding.
This is my code:
public class Main3Activity extends AppCompatActivity {
Handler handler;
TextView textView;
ImageView imageView2;
ImageView imageView3;
Boolean checker=false;
long secondtime=1000;
long roundtime1= 10000;
long roundtime2=10000;
long pause= 31000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
textView=(TextView)findViewById(R.id.textView3);
imageView2=(ImageView)findViewById(R.id.imageView2);
imageView3=(ImageView)findViewById(R.id.imageView3);
imageView2.setOnClickListener(
new ImageView.OnClickListener(){
#Override
public void onClick(View v) {
handler = new Handler();
if (checker == false) {
handler.post(r);
checker = true;
}
imageView3.setOnClickListener(
new ImageView.OnClickListener() {
#Override
public void onClick(View v) {
handler.removeCallbacks(r);
}
}
);
}
final Runnable r= new Runnable() {
#Override
public void run() {
roundtime = roundtime - secondtime;
int seconds = (int) (roundtime / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
if (roundtime >= 0) {
textView.setText(String.format("%d:%02d", minutes, seconds));
handler.postDelayed(r, 1000);
} else if (pause > 0) {
pause = pause - secondtime;
int secondss = (int) (pause / 1000);
int minutess = secondss / 60;
secondss = secondss % 60;
textView.setText(String.format("%d:%02d", minutess, secondss));
handler.postDelayed(r, 1000);
} else if (roundtime2 > 0) {
roundtime2 = roundtime2 - secondtime;
int secondsss = (int) (roundtime2 / 1000);
int minutesss = secondsss / 60;
secondsss = secondsss % 60;
textView.setText(String.format("%d:%02d", minutesss, secondsss));
handler.postDelayed(r, 1000);
}else{
textView.setText("Over");
}
}
};
}
);
}
}

Stop a stopwatch in Android

I've made a custom stop watch which showing hours:minuted:seconds.Controls are given by START and STOP buttons.But, there is a problem when stopping the stopwatch.It didn't stop when the STOP button is clicked. Anybody please suggest me the right solution.
package com.example.mystopwatch;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class StopwatchActivity extends Activity {
private TextView textViewTimer;
private Button BtnStart,BtnStop;
private Handler mHandler = new Handler();
private long startTime;
private long elapsedTime;
private final int REFRESH_RATE = 100;
private String hours,minutes,seconds,milliseconds;
private long secs,mins,hrs,msecs;
private boolean stopped = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_stopwatch);
BtnStart=(Button)findViewById(R.id.startbtn);
BtnStop=(Button)findViewById(R.id.stopbtn);
BtnStart.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Runnable startTimer1 = new Runnable()
{
public void run()
{
elapsedTime = System.currentTimeMillis() - startTime; updateTimer(elapsedTime);
mHandler.postDelayed(this,REFRESH_RATE);
}
};
if(stopped)
{
startTime = System.currentTimeMillis() - elapsedTime;
}
else
{
startTime = System.currentTimeMillis();
}
mHandler.removeCallbacks(startTimer1);
mHandler.postDelayed(startTimer1, 0);
}
});
BtnStop.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Runnable startTimer2 = new Runnable()
{
public void run()
{
elapsedTime = System.currentTimeMillis() - startTime; updateTimer(elapsedTime);
mHandler.postDelayed(this,REFRESH_RATE);
}
};
mHandler.removeCallbacks(startTimer2);
stopped = true;
}
});
}
private void updateTimer(long time) {
// TODO Auto-generated method stub
secs = (long)(time/1000);
mins = (long)((time/1000)/60);
hrs = (long)(((time/1000)/60)/60);
secs = secs % 60;
seconds=String.valueOf(secs);
if(secs == 0)
{
seconds = "00";
}
if(secs <10 && secs > 0)
{
seconds = "0"+seconds;
}
mins = mins % 60;
minutes=String.valueOf(mins);
if(mins == 0){ minutes = "00";
}
if(mins <10 && mins > 0)
{
minutes = "0"+minutes;
}
hours=String.valueOf(hrs);
if(hrs == 0)
{
hours = "00";
}
if(hrs <10 && hrs > 0)
{
hours = "0"+hours;
}
milliseconds = String.valueOf((long)time);
if(milliseconds.length()==2)
{
milliseconds = "0"+milliseconds;
}
if(milliseconds.length()<=1)
{ milliseconds = "00";
}
milliseconds = milliseconds.substring(milliseconds.length()-3, milliseconds.length()-2);
((TextView)findViewById(R.id.timertxt)).setText(hours + ":" + minutes + ":" + seconds);
}
}
Most of the code in your BtnStop.setOnClickListener is actually useless. You define a Runnable called startTimer2, but for what purpose? You never use that Runnable except in the call to mHandler.removeCallbacks(startTimer2);. That will remove any calls that were made to it before, but since you never made any, this does not do anything.
The only thing your method does when you click the stop button is to set the boolean flag stopped to true. But there is no periodic process checking that flag. The only time you check the flag is when the START button is pressed.
As a side note, your use of REFRESH_RATE is confusing. Setting a higher number will actually result in a lower refresh rate since postDelayed takes a duration. Consider renaming the variable or adding a division.
It can not stop since you don't check boolean stopped in your run method. Move it inside :
public void run() {
elapsedTime = System.currentTimeMillis() - startTime;
updateTimer(elapsedTime);
if(!stopped) {
mHandler.postDelayed(this, REFRESH_RATE);
}
}
and also consider declaring stopped as volatile as per suggestion in the comments.
there is whole task to start and stop , stopwatch just call :-- handler.sendEmptyMessage(MSG_STOP_TIMER); to stop stopwatch
Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case MSG_START_TIMER:
timer.start(); //start timer
handler.sendEmptyMessage(MSG_UPDATE_TIMER);
break;
case MSG_UPDATE_TIMER:
//timerText.setText(String.format("%1$tM:%1$tS",timer.getElapsedTimeMin(),timer.getElapsedTimeSecs()));
if ( timer.getElapsedTimeSecs() < 10)
{
if(timer.getElapsedTimeMin()<10){
timerText.setText("0" + timer.getElapsedTimeMin() + ":0" + timer.getElapsedTimeSecs());
}else{
timerText.setText("" + timer.getElapsedTimeMin() + ":0" + timer.getElapsedTimeSecs());
}
}
else{
if(timer.getElapsedTimeMin()<10){
timerText.setText("0" + timer.getElapsedTimeMin() + ":" + timer.getElapsedTimeSecs());
}else{
timerText.setText(timer.getElapsedTimeMin()+":"+ timer.getElapsedTimeSecs());
}
}
handler.sendEmptyMessageDelayed(MSG_UPDATE_TIMER,REFRESH_RATE); //text view is updated every second,
break; //though the timer is still running
case MSG_STOP_TIMER:
handler.removeMessages(MSG_UPDATE_TIMER); // no more updates.
timer.stop();//stop timer
timerText.setText("0"+timer.getElapsedTimeMin()+":0"+ timer.getElapsedTimeSecs());
break;
default:
break;
}
}
};

Categories

Resources