Update time every second - java

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

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

Issues with countdown timer android studio

I'm very new to Java and and I'm trying to make an activity that calls an countdown timer from 5:00 minutes to 0. But, I'm having some issues. I tried every example code out there. Can you guys help me?
import androidx.appcompat.app.AppCompatActivity;
import java.util.Locale;
public class Main4Activity extends AppCompatActivity {
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Fixed!
int minute;
long min;
TextView tv_timer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
tv_timer=findViewById(R.id.contador);
minute=Integer.parseInt("5");
min= minute*60*1000;
counter(min);
}
private void counter(long min) {
CountDownTimer timer = new CountDownTimer(min, 1000) {
public void onTick(long millisUntilFinished) {
int seconds = (int) (millisUntilFinished / 1000) % 60;
int minutes = (int) ((millisUntilFinished / (1000 * 60)) % 60);
tv_timer.setText(String.format("%d:%d", minutes, seconds));
}
public void onFinish() {
Toast.makeText(getApplicationContext(), "Your time has been completed",
Toast.LENGTH_LONG).show();
}
};
timer.start();
}
}

I am trying to create a countdown timer which includes days, hours, minutes and seconds of an event?

Below is the code which I have for my countdown timer displaying into a text view when I run the app. However when I run it, it does not appear.
private TextView countdowndisplay;
private Handler handler;
private Runnable runnable;
countdowndisplay = (TextView) view.findViewById(R.id.countdowntv);
countDownStart();
public void countDownStart() {
handler = new Handler();
runnable = new Runnable() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void run() {
handler.postDelayed(this, 1000);
try {
SimpleDateFormat dateFormat = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
dateFormat = new SimpleDateFormat("yyyy-MM-dd");
} else {
//Set the optional Date format here for Devices Running ANDROID VERSION BELOW N
dateFormat = new SimpleDateFormat("yyyy-MM-dd");
}
// Please here set your event date//YYYY-MM-DD
Date futureDate = dateFormat.parse("2017-09-23");
Date currentDate = new Date();
if (!currentDate.after(futureDate)) {
long diff = futureDate.getTime()
- currentDate.getTime();
long days = diff / (24 * 60 * 60 * 1000);
diff -= days * (24 * 60 * 60 * 1000);
long hours = diff / (60 * 60 * 1000);
diff -= hours * (60 * 60 * 1000);
long minutes = diff / (60 * 1000);
diff -= minutes * (60 * 1000);
long seconds = diff / 1000;
countdowndisplay.setText("" + String.format("%02d", days, hours, minutes, seconds));
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
handler.postDelayed(runnable, 1 * 1000);
}
Below is the XML which I have for the textView where I want the output to be displayed.
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/nextdrifttv"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:id="#+id/countdowntv"/>
I would do this a different way but this works using your code – android.
package com.example.coundown.countdownapp;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private TextView countdowndisplay;
private Handler handler;
private Runnable runnable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
countdowndisplay = (TextView) findViewById(R.id.coundowntimer);
countDownStart();
}
public void countDownStart() {
handler = new Handler();
runnable = new Runnable() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void run() {
handler.postDelayed(this, 1000);
try {
SimpleDateFormat dateFormat = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
dateFormat = new SimpleDateFormat("yyyy-MM-dd");
} else {
//Set the optional Date format here for Devices Running ANDROID VERSION BELOW N
dateFormat = new SimpleDateFormat("yyyy-MM-dd");
}
// Please here set your event date//YYYY-MM-DD
Date futureDate = dateFormat.parse("2017-09-23");
Date currentDate = new Date();
if (!currentDate.after(futureDate)) {
long diff = futureDate.getTime() - currentDate.getTime();
long days = diff / (24 * 60 * 60 * 1000);
diff -= days * (24 * 60 * 60 * 1000);
long hours = diff / (60 * 60 * 1000);
diff -= hours * (60 * 60 * 1000);
long minutes = diff / (60 * 1000);
diff -= minutes * (60 * 1000);
long seconds = diff / 1000;
if (countdowndisplay != null)
countdowndisplay.setText(String.valueOf(days) + " days \n" + String.valueOf(hours) + " hours \n " + String.valueOf(minutes) + " minutes \n" + String.valueOf(seconds)+ " seconds");
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
handler.postDelayed(runnable, 1 * 1000);
}
}
Try this. Your problem is updating the UI from runnable.
public class MainActivity extends AppCompatActivity {
TextView countdowndisplay;
int count=0;
Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
countdowndisplay = (TextView) findViewById(R.id.mainText);
countdowndisplay.setText("really");
countDownStart();
}
void countDownStart(){
//Post handler after 1 second.
handler.postDelayed(runnable, 1000);
}
Runnable runnable = new Runnable() {
#Override
public void run() {
count++;
handler.postDelayed(runnable, 1000);
///**Update your UI from here**///
countdowndisplay.setText(count+" Second");
}
};
}

How to stop a runnable timer at a specific condition?

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

Countdown timer still continues when onPause is called

I'm making a simple app where I start a countdown timer e.g. 25 to 0 and when the timer expires it shows a template.But when my mobile is locked timer will be paused and when i unlocked it will resume .what can i do for continues timer ??
public class MyActivity extends Activity {
TextView tvCountDown;
MyCount counter;
long countDownInterval = 1000;
#Override
public void onCreate(Bundle savedInstanceState) {
setTheme(android.R.style.Theme_Light_NoTitleBar_Fullscreen);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auth);
tvCountDown = (TextView) findViewById(R.id.tvCountDown);
counter = new MyCount(6000, countDownInterval);
counter.start();
}
public class MyCount extends CountDownTimer
{
public MyCount(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
public void onTick (long millisUntilFinished)
{
Log.v("test","onTick Seconds: "+millisUntilFinished+" : "+(millisUntilFinished / 1000));
tvCountDown.setText ( formatTime(millisUntilFinished));
System.out.print("");
}
public void onFinish() {
tvCountDown.setText("done!");
}
public String formatTime(long millis)
{
String output = "00:00:00";
long seconds = millis / 1000;
long minutes = seconds / 60;
long hours = minutes / 60;
seconds = seconds % 60;
minutes = minutes % 60;
hours = hours % 60;
String secondsD = String.valueOf(seconds);
String minutesD = String.valueOf(minutes);
String hoursD = String.valueOf(hours);
if (seconds < 10)
secondsD = "0" + seconds;
if (minutes < 10)
minutesD = "0" + minutes;
if (hours < 10)
hoursD = "0" + hours;
output = hoursD + " : " + minutesD + " : " + secondsD;
return output;
}
}
Just call .cancel() method when your activity/fragment going to destroy.
If you want to pause/resume yout timer go for this answer;

Categories