How to stop a runnable timer at a specific condition? - java

I want to make a Timer Application which plays an alarm after a specific time has elapsed. I am new to Android Development so i picked up an example timer code from the Internet and am trying to modify it to my needs.
I have completed part where the timer plays the alarm when 1 minute has elapsed, but the alarm sound does not stop how can i do that.
My code is given below:
package com.example.aditya.timerapp;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.api.GoogleApiClient;
public class MainActivity extends AppCompatActivity {
private ProgressBar progress;
private TextView timerValue;
private long startTime = 0L;
private Handler customHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
int progressStatus = 0;
private boolean stopped = false;
#Override
public void onCreate(Bundle savedInstanceState) {
//final CountDown timer = new CountDown();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerValue = (TextView) findViewById(R.id.timerVal);
Button startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//timer.start();
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
}
});
Button pauseButton = (Button) findViewById(R.id.stopButton);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
/*try {
timer.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}*/
timeSwapBuff += timeInMilliseconds;
customHandler.removeCallbacks(updateTimerThread);
}
});
Button resetButton = (Button) findViewById(R.id.resetButton);
resetButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
//timeSwapBuff += timeInMilliseconds;
timeInMilliseconds = 0L;
timeSwapBuff = 0L;
updatedTime = 0L;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
timerValue.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
customHandler.removeCallbacks(updateTimerThread);
onStop();
}
});
progress = (ProgressBar) findViewById(R.id.progressBar);
}
/*public void stopRun() {
//if (updatedTime == 0) {
//Toast.makeText(new MainActivity(), "StopRun",Toast.LENGTH_LONG).show();
timeSwapBuff = 0;
timerValue.setText("00:00:000");
//updateTimerThread.
customHandler.removeCallbacks(updateTimerThread);
//}
}*/
private Runnable updateTimerThread = new Runnable() {
#Override
public void run() {
//long totalMilliseconds = 1500000;
//while (!stopped){
//long totalMilliseconds = 15000;
//updatedTime = totalMilliseconds - SystemClock.currentThreadTimeMillis();
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
timerValue.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
if (mins == 1 && secs == 0) {
playTimer();
}
}
};
public ProgressBar getProgress() {
return progress;
}
public void setProgress(ProgressBar progress) {
this.progress = progress;
}
public void playTimer(){
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
Ringtone ring = RingtoneManager.getRingtone(getApplicationContext(), notification);
ring.play();
timeSwapBuff += timeInMilliseconds;
customHandler.removeCallbacks(updateTimerThread);
}
protected void onStop() {
customHandler.removeCallbacks(updateTimerThread);
super.onStop();
}
}
So now i need a method to stop the alarm when the user presses the Reset Button. Please suggest.

One way to do it is as follows:
Define a boolean inside your Runnable and check it before doing anything in run().
Flip it using a method inside your Runnable.
Here is the code snippet:
private Runnable updateTimerThread = new Runnable() {
private volatile boolean flag = true;
public void stopTimer() {
this.flag = false;
}
#Override
public void run() {
while(flag) {
//long totalMilliseconds = 1500000;
//while (!stopped){
//long totalMilliseconds = 15000;
//updatedTime = totalMilliseconds - SystemClock.currentThreadTimeMillis();
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
timerValue.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
if (mins == 1 && secs == 0) {
playTimer();
}
}
}
};
Now, you just have to call stopTimer() to stop the Runnable.
Another way could be to handle the InterruptedException in the Runnable and send an interrupt from the main program.

If I understood question right,you can try to stop alarm sound by declaring your private Ringtone ring and call ring.stop() method in your onStop() method.
private Ringtone ring;
//...//
public void playTimer(){
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
ring = RingtoneManager.getRingtone(getApplicationContext(), notification);
ring.play();
timeSwapBuff += timeInMilliseconds;
customHandler.removeCallbacks(updateTimerThread);
}
protected void onStop() {
customHandler.removeCallbacks(updateTimerThread);
ring.stop();
super.onStop();
}

Related

How do you find the time difference between onStop and onCreate lifecycle callbacks?

I am an absolute beginner and was trying to code a Count-up-timer app that will run in the background, in other words when the app is closed from overview or when the back button is pressed, the timer will still appear to continue on the corrected time the next time the app is opened. I tried to do this by using SharedPreferences.
An error that I run into is that when I launch the emulator, the timer does not start at 00:00:00 as it should, however, it starts at random times. Here is a screenshot
public class MainActivity extends AppCompatActivity {
TextView timerText;
TextView dayText;
Button startStopButton;
Timer timer;
TimerTask timertask;
Double time = 0.0;
Double mEndTime = 0.0;
Double startingSysTime = 0.0;
Double timeGap = 0.0;
public static final String SHARED_PREFS ="sharedPrefs";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerText = (TextView) findViewById(R.id.timerText);
startStopButton = (Button) findViewById(R.id.startStopButton);
dayText = (TextView) findViewById(R.id.dayText);
timer = new Timer();
SharedPreferences prefs = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
time = Double.longBitsToDouble(prefs.getLong("mTimeValue", Double.doubleToLongBits(0.0)));
mEndTime = Double.longBitsToDouble(prefs.getLong("onDestr_SysTime", Double.doubleToLongBits(0.0)));
if(mEndTime==0.0){
startingSysTime = 0.0;
}else{
startingSysTime = (double) (System.currentTimeMillis());
}
timeGap = startingSysTime - mEndTime;
time += timeGap;
startTimer();
}
#Override
protected void onStop() {
super.onStop();
Log.i("TIMEGAP", "onStop called");
SharedPreferences prefs = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putLong("mTimeValue", Double.doubleToRawLongBits(time)); //saves the time value
editor.putLong("onDestr_SysTime", Double.doubleToRawLongBits(System.currentTimeMillis())); //saves the CurrentSystemTime when onStop is invoked
editor.apply();
}
private void startTimer() {
timertask = new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
time++;
timerText.setText(getTimerText());
dayText.setText(getDayText());
}
});
}
};
timer.scheduleAtFixedRate(timertask, 0, 1000);
}
private String getDayText() {
int rounded = (int) Math.round(time);
int days = (rounded / 86400);
return formatDay(days);
}
private String formatDay(int days) {
String pluralDays;
if (days == 1) {
pluralDays = " Day";
} else {
pluralDays = " Days";
}
return days + pluralDays;
}
private String getTimerText() {
int rounded = (int) Math.round(time);
int seconds = ((rounded % 86400) % 3600) % 60;
int minutes = ((rounded % 86400) % 3600) / 60;
int hours = ((rounded % 86400) / 3600);
return formatTime(seconds, minutes, hours);
}
private String formatTime(int seconds, int minutes, int hours) {
return String.format("%02d", hours) + " : " + String.format("%02d", minutes) + " : " + String.format("%02d", seconds);
}
EDIT: Problem fixed, I simply had to convert timeGap to seconds by dividing it by 1000
timeGap = (startingSysTime - mEndTime)/1000;
Try this way
Handler.postDelayed(new Runnable{
//Todo write your code here
handler.postdelayed(this,1000);
},1000);
Start where you need
long starttime;
start time = System.currentTimeMilisecond();
End where you need
long currtime = System.currentTimeMilisecond() - startime;
}
According to your question try to convert this millisecond in your format which you need. Store long value in shared preference if you want to manage this on app close also

Unable to use String variable outside if statement

I have implemented timer like this (Mentioned in code). I changed its string format so that it takes hours:minutes:seconds and for me, to use a switch, I have to add an if(){} conditional statement.
So I did and I had to declare the string inside the if(){} cause i couldnt do it outside if(){}. But now I want to use that string information for an intent to open a new activity and assign the string value to a TextView.
The problem is I can't use the string outside of the if(){} and at first I used the hms string with a TextView called myText.
The thing is that the myText TextView worked perfectly on the first activity but when sending the information using Inetnt to another Textview in the other activity it showed no change on the TextView.
Heres is the code:
if (mySwitch.isChecked()) {
int getvaluehour = numPickerHour.getValue();
int getvalueminute = numPickerMin.getValue();
getvaluehour = getvaluehour * 3600000;
getvalueminute = getvalueminute * 60000;
long hoursandMinstomils = getvalueminute + getvaluehour;
new CountDownTimer(hoursandMinstomils, 1000) {
public void onTick(long millisUntilFinished) {
//here you can have your logic to set text to edittext
long millis = millisUntilFinished;
//Convert milliseconds into hour,minute and seconds
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
myText.setText(hms);
}
public void onFinish() {
myText.setText("TIME'S UP!!"); //On finish change timer text
}
}.start();
and heres how i used the Intent Activity1:
Intent toST = new Intent(MainActivity.this, ShowTime.class);
String textMessage = myText.getText().toString() ;
toST.putExtra("wargra", textMessage);
startActivity(toST);
and heres how I received it in activity2:
Bundle receiver = getIntent().getExtras();
if(receiver == null){
return;
}
String textMessage = reciver.getString("wargra");
myText2.setText(textMessage);
How can I send hms value to myText2?
Here is the complete activity1 code:
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
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.NumberPicker;
import android.widget.Switch;
import android.widget.TextView;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
Button silentButton;
AudioManager myAudioManager;
NumberPicker numPickerHour;
NumberPicker numPickerMin;
Switch mySwitch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Text,Audio,Button,Time
myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
silentButton = (Button) findViewById(R.id.Start);
//Number Picker
numPickerHour = (NumberPicker) findViewById(R.id.numberPickerHour);
numPickerMin = (NumberPicker) findViewById(R.id.numberPickerMinute);
mySwitch = (Switch) findViewById(R.id.Toggle);
//Hour
numPickerHour.setMaxValue(24);
numPickerHour.setMinValue(0);
numPickerHour.setWrapSelectorWheel(true);
//Min
numPickerMin.setMaxValue(60);
numPickerMin.setMinValue(0);
numPickerMin.setWrapSelectorWheel(true);
silentButton.setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
final TextView myText;
myText = (TextView)findViewById(R.id.timeText);
if (mySwitch.isChecked()) {
int getvaluehour = numPickerHour.getValue();
int getvalueminute = numPickerMin.getValue();
getvaluehour = getvaluehour * 3600000;
getvalueminute = getvalueminute * 60000;
long hoursandMinstomils = getvalueminute + getvaluehour;
new CountDownTimer(hoursandMinstomils, 1000) {
public void onTick(long millisUntilFinished) {
//here you can have your logic to set text to edittext
long millis = millisUntilFinished;
//Convert milliseconds into hour,minute and seconds
String hms = String.format("Viberation end in: " + "%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
myText.setText(hms);
//set text
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
}
public void onFinish() {
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
myText.setText("TIME'S UP!!"); //On finish change timer text
}
}.start();
} else {
int getvaluehour = numPickerHour.getValue();
int getvalueminute = numPickerMin.getValue();
getvaluehour = getvaluehour * 3600000;
getvalueminute = getvalueminute * 60000;
long hoursandMinstomils = getvalueminute + getvaluehour;
new CountDownTimer(hoursandMinstomils, 1000) {
public void onTick(long millisUntilFinished) {
//here you can have your logic to set text to edittext
long millis = millisUntilFinished;
//Convert milliseconds into hour,minute and seconds
String hms = String.format("Silent ends in (" + "%02d:%02d:%02d" + ")", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
myText.setText(hms);//set text
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}
public void onFinish() {
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
myText.setText("TIME'S UP!!"); //On finish change timer text
}
}.start();
}
Intent toST = new Intent(MainActivity.this, ShowTime.class);
String textMessage = myText.getText().toString() ;
toST.putExtra("wargra", textMessage);
startActivity(toST);
}
}
);
}
}
final TextView myText;
myText = (TextView)findViewById(R.id.timeText);
Change these two lines. Declare myText globally (as you have already done with silentButton, myAudioManager, numPickerHour, numPickerMin, mySwitch).
public class MainActivity extends AppCompatActivity {
//Following your other code
....
TextView myText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Following your other code
....
myText = (TextView)findViewById(R.id.timeText);
//Rest of your code
....
}
}
Hope your problem will be gone.
There could be two reasons and solutions:
case 1: If you are using your if inside a Thread then you should update the TextView on UIThread i.e MainThread.
Like this:
if (mySwitch.isChecked()) {
int getvaluehour = numPickerHour.getValue();
int getvalueminute = numPickerMin.getValue();
getvaluehour = getvaluehour * 3600000;
getvalueminute = getvalueminute * 60000;
long hoursandMinstomils = getvalueminute + getvaluehour;
new CountDownTimer(hoursandMinstomils, 1000) {
public void onTick(long millisUntilFinished) {
//here you can have your logic to set text to edittext
long millis = millisUntilFinished;
//Convert milliseconds into hour,minute and seconds
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
MainActivity.this.runOnUIThread(new Runnable()
{
#Override
public void run()
{
myText.setText(hms);
}
}).start();
}
public void onFinish() {
MainActivity.this.runOnUIThread(new Runnable()
{
#Override
public void run()
{
myText.setText("TIME'S UP!!"); //On finish change timer text
}
}).start();
}
}.start();
You should always update any UI element on MainThread only by using the runOnUIThread() method. May be this was the cause of your problem.
case 2: Solution given by Sudip Podder.
case 3 : Answer to your query :
In java you can not just use a variable outside of its scope. All you can do the thing is to put the value to class variable like this :
Just declare a class variable and put value in it and then use the class variable for the values.
public class MainActivity extends AppCompatActivity {
....
....
String time;
....
....
}
....
....
....
if (mySwitch.isChecked()) {
int getvaluehour = numPickerHour.getValue();
int getvalueminute = numPickerMin.getValue();
getvaluehour = getvaluehour * 3600000;
getvalueminute = getvalueminute * 60000;
long hoursandMinstomils = getvalueminute + getvaluehour;
new CountDownTimer(hoursandMinstomils, 1000) {
public void onTick(long millisUntilFinished) {
//here you can have your logic to set text to edittext
long millis = millisUntilFinished;
//Convert milliseconds into hour,minute and seconds
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis), TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)), TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
MainActivity.this.time=hms;
MainActivity.this.runOnUIThread(new Runnable()
{
#Override
public void run()
{
myText.setText(MainActivity.this.time);
}
}).start();
}
public void onFinish() {
MainActivity.this.runOnUIThread(new Runnable()
{
#Override
public void run()
{
myText.setText("TIME'S UP!!"); //On finish change timer text
}
}).start();
Now you can use the value of hms variable by the class variable time. And yes don't forget to declare myText as class variable.

How do i reset the timer to start from 00:00:00 each time i run my program over again?

I added to MainActvitiy.java
private Button startButton;
private Button pauseButton;
private TextView timerValue;
private long startTime = 0L;
private Handler customHandler = new Handler();
long timeInMilliseconds = 0L;
long timeSwapBuff = 0L;
long updatedTime = 0L;
Then in the onCreate i added:
And did that the timer will start automatic when i run the program without the need to click the start button i want the timer to start right when i run my program.
customHandler.postDelayed(updateTimerThread,0);
timerValue = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
}
});
pauseButton = (Button) findViewById(R.id.pauseButton);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
timeSwapBuff += timeInMilliseconds;
customHandler.removeCallbacks(updateTimerThread);
}
});
Then the method updateTimerThread:
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = 0L;//SystemClock.uptimeMillis() - startTime;
timeInMilliseconds = SystemClock.uptimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
timerValue.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
}
};
In this method i did:
timeInMilliseconds = 0L;
But it didn't change much.
what i want to do is each time i run my program from the beginning the timer will start from 00:00:00
EDIT
In the on activity i did now this:
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread,0);
timerValue = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
}
});
pauseButton = (Button) findViewById(R.id.pauseButton);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
timeSwapBuff += timeInMilliseconds;
customHandler.removeCallbacks(updateTimerThread);
}
});
In the upadteTimerThread i didn't change:
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilliseconds = System.currentTimeMillis() - startTime;
updatedTime = timeSwapBuff + timeInMilliseconds;
int secs = (int) (updatedTime / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (updatedTime % 1000);
timerValue.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
customHandler.postDelayed(this, 0);
}
};
Still when running the program the timer is not starting from 00:00:00 but i see on the minutes a long number also in second like it's continuing not starting over like reseted.
In the startButton onClick method, you have:
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
But at the top, you only have:
customHandler.postDelayed(updateTimerThread,0);
Since updateTimerThread uses the startTime value, you'd very likely want to initialize it the same way at the top.
The key to resetting the timer back to zero is in the updatedTime variable. This is what determines where the timer starts when you press the Start button.
There's no need to reinitialize the startTime variable since startTime = SystemClock.uptimeMillis(); already properly sets the startTime back to 0. Remember that startTime is relative to what's currently showing on the timer. That's why the timer starts off where you paused it and doesn't skip the seconds for when the timer was paused.
Set the timeSwapBuff back to 0L in the onClick event for the Start Button. This resets the time buffer to 0. That then gets added back to the startTime (also 0) and forces the timer to start over completely.
Try:
public void onClick(View view) {
timeSwapBuff = 0L;
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
}

Update time every second

I need to update time every second on a countdown timer which counts down to Christmas.
How do I update the time in my text view.I do not have the code in the onCreate method.
here is some of my code. When I run the code it gives the exact time, but it does not countdown live on screen. Any ideas?
Edit: the readThisPeriod is for calculating the time left until Christmas.
public void DateCalculator() {
Calendar today = Calendar.getInstance();
Calendar thatDay = Calendar.getInstance();
thatDay.set(Calendar.DAY_OF_MONTH, 25);
thatDay.set(Calendar.MONTH, 11); // 0-11 so 1 less
thatDay.set(Calendar.YEAR, 2014);
thatDay.set(Calendar.HOUR, 0);
thatDay.set(Calendar.MINUTE, 0);
thatDay.set(Calendar.SECOND, 0);
thatDay.set(Calendar.AM_PM, 0);
System.out.println(thatDay.getTime());
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(new ReadThisPeriod(thatDay), 0, 1,
TimeUnit.SECONDS);
long diff = (thatDay.getTimeInMillis() - today.getTimeInMillis()) / 1000;
long days = diff / (60 * 60 * 24);
long hours = diff / (60 * 60) % 24;
long minutes = diff / 60 % 60;
long seconds = diff % 60;
daysBox = (TextView) findViewById(R.id.s1Days);
daysBox.setText("" + "" + days + "" + hours + "" + minutes + "" + seconds + " );
}
Start a CountDownTimer :
long endTime = thatDay.getTimeInMillis();
new MyCountDownTimer(endTime-System.currentTimeMillis(),1000).start();
Here you go:
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
textView.setText("Happy Christmas!");
}
#Override
public void onTick(long millis) {
int SECOND = 1000;
int MINUTE = 60 * SECOND;
int HOUR = 60 * MINUTE;
int DAY = 24 * HOUR;
StringBuffer text = new StringBuffer();
if (millis > DAY) {
text.append(millis / DAY).append(" days ");
millis %= DAY;
}
if (millis > HOUR) {
text.append(millis / HOUR).append(" hours ");
millis %= HOUR;
}
if (millis > MINUTE) {
text.append(millis / MINUTE).append(" minutes ");
millis %= MINUTE;
}
if (millis > SECOND) {
text.append(millis / SECOND).append(" seconds ");
millis %= SECOND;
}
textView.setText(text);
}
}
import android.app.Activity;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import java.util.Calendar;
public class MainActivity extends Activity {
private TextView daysBox;
private boolean running;
private Calendar thatDay;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
daysBox = (TextView) findViewById(R.id.main_day);
thatDay = Calendar.getInstance();
thatDay.set(Calendar.DAY_OF_MONTH, 25);
thatDay.set(Calendar.MONTH, 11); // 0-11 so 1 less
thatDay.set(Calendar.YEAR, 2014);
thatDay.set(Calendar.HOUR, 0);
thatDay.set(Calendar.MINUTE, 0);
thatDay.set(Calendar.SECOND, 0);
thatDay.set(Calendar.AM_PM, 0);
startDateCalculator();
}
protected void onPause() {
super.onPause();
running = false;
}
protected void onResume() {
super.onResume();
running = true;
}
private class CountdownTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... args) {
while (running) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
publishProgress();
}
return null;
}
protected void onProgressUpdate(Void... res) {
super.onProgressUpdate(res);
long diff = (thatDay.getTimeInMillis() - System.currentTimeMillis()) / 1000;
long days = diff / (60 * 60 * 24);
long hours = diff / (60 * 60) % 24;
long minutes = diff / 60 % 60;
long seconds = diff % 60;
daysBox.setText("" + "" + days + "d " + hours + ":" + minutes + ":" + seconds + " ");
}
}
public void startDateCalculator() {
new CountdownTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
long diff = (thatDay.getTimeInMillis() - today.getTimeInMillis()) / 1000;
long total=diff;
mTimer=new CountDownTimer(total, 1000) {
public void onTick(long millisUntilFinished) {
diff--;
daysBox.setText(convertSecondToHHMMString(diff));
}
public void onFinish() {
System.out.println("Happy Chrismas");
}
}.start();
private String convertSecondToHHMMString(long secondtTime){
TimeZone tz = TimeZone.getTimeZone("UTC");
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
df.setTimeZone(tz);
String time = df.format(new Date(secondtTime*1000L));
return time;
}

android developers - timer application

I wrote a timer code. the clear function doesn't clear the time value (when I press clear only the text changes, but the time value continues form stop point) here is the code, any suggestions to activate the clear button?:
public class MainActivity extends Activity {
private Button startButton;
private Button stopButton;
private Button clearButton;
private TextView timeValue;
private long timeStart = 0L;
private Handler timeHandler = new Handler();
long timeInMilisec = 0L;
long timeMemo = 0L;
long timeUpdate = 0L;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timeValue = (TextView) findViewById(R.id.timeValue);
startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
timeStart = SystemClock.uptimeMillis();
timeHandler.postDelayed(updateTimerThread, 0);
}
});
stopButton = (Button) findViewById(R.id.stopButton);
stopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
timeMemo += timeInMilisec;
timeHandler.removeCallbacks(updateTimerThread);
}
});
clearButton = (Button) findViewById(R.id.clearButton);
clearButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.clearButton:
timeValue.setText("00:00:00");
int secs = 0;
int mins = 0;
secs = 0;
int milliseconds = 0;
timeInMilisec = SystemClock.uptimeMillis() - timeStart;
timeUpdate = timeMemo + timeInMilisec;
timeValue.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
timeHandler.removeCallbacksAndMessages(updateTimerThread);
timeValue.setText("00:00:00");
break;
}
}
});
}
private Runnable updateTimerThread = new Runnable() {
public void run() {
timeInMilisec = SystemClock.uptimeMillis() - timeStart;
timeUpdate = timeMemo + timeInMilisec;
int secs = (int) (timeUpdate / 1000);
int mins = secs / 60;
secs = secs % 60;
int milliseconds = (int) (timeUpdate % 1000);
timeValue.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
timeHandler.postDelayed(this, 0);
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
You should reset the timeMemo variable.
clearButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.clearButton:
// Clear the timestart and timeMemo
timeMemo = 0L;
timeValue.setText("00:00:00");
int secs = 0;
int mins = 0;
secs = 0;
int milliseconds = 0;
timeInMilisec = SystemClock.uptimeMillis() - timeStart;
timeUpdate = timeMemo + timeInMilisec;
timeValue.setText("" + mins + ":"
+ String.format("%02d", secs) + ":"
+ String.format("%03d", milliseconds));
timeHandler.removeCallbacksAndMessages(updateTimerThread);
timeValue.setText("00:00:00");
timeHandler.removeCallbacks(updateTimerThread);
break;
}
}
});
In the ClearButton onClick you are not reseting the value of the "timerstart" and "timeMemo" variables. That is why only the text is being updated but the timer is not being reset.

Categories