Running a method every second starting on button press - java

I need a timer to start any time I press a button (on the button itself) that shows how many seconds it's been since it's pressed in real time. Whenever it's pressed again, timer is reset to 0 and starts incrementing again
I know this isn't the way to do it, the button works fine but the timer should be in onCreate? I'm not sure how this is supposed to work with a button
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
downloadedImg = (ImageView) findViewById(R.id.imageView);
}
public void clickAsync(View view) {
new ImageDownloader().execute(downloadUrl);
int seconds = 0;
Button button = (Button) view;
button.setText("Seconds since clicked: " + seconds);
Timer timer = new Timer();
//each time button is clicked, time is reset to 0 and increments in real time
timer.scheduleAtFixedRate(new TimerTask()
{
public void run()
{
seconds = 0;
seconds++;
button.setText("Seconds since clicked: " + seconds);
}
}, 0, 1000);
}
}

Another easy way to do this is to use Handler
mHandler = new Handler();
Just call updateSec();method on click of a button it'll update sec in interval of one seconds
Runnable UpdateRunnable = new Runnable() {
#Override
public void run() {
updateSec();
}
};
public void updateSec() {
mSeconds++;
mHandler.postDelayed(UpdateRunnable, 1000);
}
Example
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
mSeconds = 0;
updateSec();//it'll update sec variable every second.
}
});

try this: use a handler
long startTime = 0;
long elapsedTime ;
//runs without a timer by reposting this handler at the end of the runnable
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
int hours = minutes / 60;
seconds = seconds % 60;
//textview for displaying time..
timerTextView.setText(String.format("%d:%02d:%02d", hours, minutes, seconds));
timerHandler.postDelayed(this, 1000);
}
};
b.setOnClickListener(new View.OnClickListener() { //b is your button
#Override
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals("Stop")) {
elapsedTime = System.currentTimeMillis() - startTime;
timerHandler.removeCallbacks(timerRunnable);
b.setText("Resume");
} else {
startTime = System.currentTimeMillis() - elapsedTime;
timerHandler.postDelayed(timerRunnable, 0);
Calendar cs = Calendar.getInstance();
System.out.println("Current time => " + cs.getTime());
SimpleDateFormat df = new SimpleDateFormat("HH:mm");
String formattedDate = df.format(cs.getTime());
timerTextView.setText(formattedDate);
b.setText("Stop");
}
}
});
it will calculate the elapsed time and show time after stop...

You can use threads:
#Override
public void onClick(View view){
switch(view.getId()){
case R.id.button:
new Thread(new Runnable() {
#Override
public void run() {
try{
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
count++;
textView.post(new Runnable() {
#Override
public void run() {
textView.setText(count + "");
}
});
}
}
}).start;
break;
}
}
the view must be updated on main thread, and so you need to use post() method that has runnable instance as parameter.
Alternatively, you can also use AsyncTask.

Related

how to make program read stopwatch and then print statement in another textview box when time reaches that second

I want to make a stopwatch. when my stopwatch reaches 1 minute I want it to print a statement, how can i make it do this?
I am using android studio(java), Here is a bit of my code:
Button btnStart,btnPause,btnLap;
TextView txtTimer;
Handler customHandler = new Handler();
LinearLayout container;
TextView lt;
long startTime=0L,timeinMilliseconds=0L,timeSwapBuff=0L,updateTime=0L;
Runnable updateTimerThread = new Runnable() {
#Override
public void run() {
timeinMilliseconds = SystemClock.uptimeMillis() -startTime;
updateTime = timeSwapBuff+timeinMilliseconds;
int secs=(int) (updateTime/1000);
int mins=secs/60;
secs%=60;
int milliseconds=(int) (updateTime%1000);
String s = "" + mins + ":" + String.format("%02d",secs) + ":" + String.format("%03d",milliseconds);
txtTimer.setText (s);
customHandler.postDelayed(this,0);
}
};
If you just want to setText after some X minutes just create a method like this:
private void printText(int minutes) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do you setText here
}
}, minutes * 1000);
}
and use it like:
printText(1);
Update:
Chronometer is exactly what you are looking for.
It extends TextView, so just replace your timer textview with Chronometer
mChronometer = findViewById(R.id.chronometer2);
mChronometer.setBase(SystemClock.elapsedRealtime());
mChronometer.start();
mChronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
#Override
public void onChronometerTick(Chronometer chronometer) {
long elapsedMillis = SystemClock.elapsedRealtime() - mChronometer.getBase();
int secs = (int) (elapsedMillis/1000);
int mins = secs/60;
if (mins == 1) {
mChronometer.stop();
anotherTextVeiw.setText("the 1 minute mark has passed");
}
}
});
You don't have to deal with Handler and Runnable with this approach

android - countdown timer is not canceling

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();
}

Pausing a CountDownTimer whilst another one runs - Android

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

Java/Android Countdown timer

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

Android: Pause/Resume Timer OR Thread

I have checked all SO answers about how to pause/resume timer, but can't find a solution.
I have created a Timer task which counts the effort time for an employee and puts it inside a TextView to show.
Code below:
Timer T = new Timer();
T.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
String workingTime = "Your effort is "
+ format.format(Double.valueOf(hr)) + ":"
+ format.format(Double.valueOf(min)) + ":"
+ format.format(Double.valueOf(sec))
+ " till now for the day";
storeEffort.setText(workingTime);
sec++;
if (sec > 59) {
sec = 0;
min = min + 1;
}
if (min > 59) {
min = 0;
hr = hr + 1;
}
}
});
}
}, 1000, 1000);
where storeEffort is my TextView which shows the effort time which is stuck inside the running thread(main problem). I want to pause the effort timer with a button click and resume it when the same button clicked again.Is there any other way to do this kind of task?
You solution might have a slight problem - you are using timer to count time intervals whereas there is no need to. You could use i.e. StopWatch to count elapsed time. So instead of adding seconds in a timer job you could just get elapsed time from this timer. To pause the timer you could call stopWatch.stop() and to start it, you could call stopWatch.start().
It could look like this:
Stopwatch stopwatch = Stopwatch.createStarted();
void startThreadUpdateTimer(){}
Timer T = new Timer();
T.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
String workingTime = "Your effort is " + sw.toString() +
" till now for the day";
}
});
}
}, 1000, 1000);
}
public void pause(){
if(stopwatch.isRunning()){
stopwatch.stop();
}
}
public void resume(){
if(!stopwatch.isRunning()){
stopwatch.start();
}
}
UPDATE Solution if the timer needs to start from beginning every second time:
public class YourOuterClass extends Activity {
private YourTimerTask mTimerTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button;
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mTimerTask != null && mTimerTask.isTaskActive()) {
mTimerTask.deactivateTimer();
mTimerTask = null;
} else {
startTask();
}
}
});
...
}
private class YourTimerTask extends TimerTask {
private boolean mIsTimerActive;
public YourTimer() {
mIsTimerActive = true;
}
public void deactivateTimer() {
mIsTimerActive = false;
}
public boolean isTaskActive() {
return mIsTimerActive;
}
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
String workingTime = "Your effort is "
+ format.format(Double.valueOf(hr)) + ":"
+ format.format(Double.valueOf(min)) + ":"
+ format.format(Double.valueOf(sec))
+ " till now for the day";
if (!mIsTimerActive) {
cancel(); // will cancel this timer instance
}
sec++;
if (sec > 59) {
sec = 0;
min = min + 1;
}
if (min > 59) {
min = 0;
hr = hr + 1;
}
}
});
}
}
...
private void startTask() {
Timer T = new Timer();
mTimerTask = new YourTimertask();
T.scheduleAtFixedRate(mTimerTask, 1000, 1000);
}
}

Categories