Hello i am creating a timer in my app but i stuck in getting seconds left in day end from now (12.00 AM) my timer basically need to show time left for today 11-59 PM. I successfully created a timer function which takes inputs in seconds and then start countdown but i am unable to calculate remaining time of today in seconds
Below is my timer function
time = 30;
// Here i need time left for today end for example current time is 11.55 then remaining time is 5 minutes in seconds (300)
public void startTimer() {
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
textTimer.setText("0:"+checkDigit(time));
time--;
}
public void onFinish() {
textTimer.setText("try again");
}
}.start();
}
public String checkDigit(int number) {
return number <= 9 ? "0" + number : String.valueOf(number);
}
remaining time of today in seconds:
Calendar tomorrow = Calendar.getInstance();// creating a calendar for tomorrow at 12am
tomorrow.add(Calendar.DAY_OF_YEAR, 1);
tomorrow.set(Calendar.HOUR_OF_DAY, 0);
tomorrow.set(Calendar.MINUTE, 0);
tomorrow.set(Calendar.SECOND, 0);
tomorrow.set(Calendar.MILLISECOND, 0);
remainingSeconds = ( tomorrow.getTimeInMillis() - System.currentTimeMillis() ) / 1000
Related
I have developed a workout app. I've two timers on the screen one is for the total timer and one for exercise time also some tts and MediaPlayer sounds. When the screen is locked my exercise timer is stuck after 10 seconds but my total remaining time timer is still running. So confused about why is it happening, I've verified battery optimization permission on\off but the issue is still the same. I've set a toast in tick function and I turn off the screen when I come back toast is showing but my timer is stuck. Can anyone help to get out of this? Thanks in advance. Countdown works fines when the screen is opened or connected to the charger.
Exercise Timer code below...
excerciseCountDownTimer = new CountDownTimer(seconds * 1000, 1000) {
public void onTick(long millisUntilFinished) {
totalExcerciseSec = (int) (millisUntilFinished / 1000);
int currentMinute = totalExcerciseSec / 60;
int currentSecond = totalExcerciseSec % 60;
binding.workoutTimeTv.setText(String.format("%02d", currentMinute) + ":" + String.format("%02d", currentSecond));
if (totalExcerciseSec == 0) {
totalRemaingCountDownTimer.cancel();
onExerciseCompleteActions();
}
}
public void onFinish() {
}
}.start();
Total Remaining Timer code below...
totalRemaingCountDownTimer = new CountDownTimer(seconds * 1000, 1000) {
public void onTick(long millisUntilFinished) {
totalRemainingSecs = (int) (millisUntilFinished / 1000);
int minutes = totalRemainingSecs / 60;
int second = totalRemainingSecs % 60;
timerPlaying = true;
binding.totalRemainingTimeTv.setText(String.format("%02d", minutes) + ":" + String.format("%02d", second));
}
public void onFinish() {
}
}.start();
Your activity is getting stopped or destroyed and that's why your timer gets stuck.
To keep the timer running even if the app is closed or killed, see this way:-
You can use this technique to detect how long the user was inactive (even when the app is in the background).
Create a SharedPreference & its Editor object. Then declare 3 long variables such:
mMillisUntilFinished = pref.getLong("millisUntilFinished",60*1000); // Replace with your time
long userExitedMillis = pref.getLong("userExitedMillis",0);
long timeLeft = mMillisUntilFinished - (System.currentTimeMillis() - userExitedMillis);
Pass timeLeft as millisInFuture. Inside timer, assign millisUntilFinished to a public variable in every tick
new CountDownTimer(timeLeft,1000){
#Override
public void onTick(long millisUntilFinished) {
Log.d("TAG", "Time left : " + millisUntilFinished/1000 + " sec");
mMillisUntilFinished = millisUntilFinished;
}
#Override
public void onFinish() {
// Timer completed
}
}.start();
Save this mMillisUntilFinished variable & current time in shared preference at onStop().
#Override
protected void onStop() {
super.onStop();
editor.putLong("millisUntilFinished",mMillisUntilFinished);
editor.putLong("userExitedMillis",System.currentTimeMillis());
editor.apply();
}
Tip : If you subtract userExitedMillis from System.currentTimeMillis() then you will get the activity inactive time (in mili second).
I have used this class to solve my issue according to my requirements.
https://gist.github.com/Gautier/737759
I can set only minutes on my countdown using edit text, how about it can set also seconds on edit text on the countdown timer, any help guys don't have any clue how to set seconds
public void onClick(View v) {
switch (v.getId()) {
case R.id.startTimer:
//If CountDownTimer is null then start timer
if (countDownTimer == null) {
String getMinutes = minutes.getText().toString();//Get minutes from edittexf
//Check validation over edittext
if (!getMinutes.equals("") && getMinutes.length() > 0) {
int noOfMinutes = Integer.parseInt(getMinutes) * 60 * 1000;//Convert minutes into milliseconds
startTimer(noOfMinutes);//start countdown
startTimer.setText(getString(R.string.stop_timer));//Change Text
} else
Toast.makeText(MainActivity.this, "Please enter no. of Minutes.", Toast.LENGTH_SHORT).show();//Display toast if edittext is empty
} else {
//Else stop timer and change text
stopCountdown();
startTimer.setText(getString(R.string.start_timer));
}
break;
case R.id.resetTimer:
stopCountdown();//stop count down
startTimer.setText(getString(R.string.start_timer));//Change text to Start Timer
countdownTimerText.setText(getString(R.string.timer));//Change Timer text
break;
}
}
You can try this to show minutes and seconds:
new CountDownTimer(90000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
String text = String.format(Locale.getDefault(), "Time Remaining %02d min: %02d sec",
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60);
tvTime.setText(text);
}
});
Change the initialization of countDownTimer according to your needs
IMO, startTimer accepts milliseconds as its parameters. You cannot set the Timer in seconds there. But use this to show seconds:
startTimer.setText(Integer.parseInt(getString(R.string.stop_timer)) / 1000);
This shows the timer in Seconds.
Hope it helps.
I have a service with a timer in the background. This timer executes a certain task after 20 seconds pass. I want the same timer to execute another task, but in a different amount of seconds. This would be easy by launching both services at the same time, but I am trying to learn how I can do it this other way.
I tried this, but it isn't showing up:
cdt = new CountDownTimer(20000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
Log.v(TAG, /*"Time remaining " +*/ (millisUntilFinished / 1000) + " seconds left");
if(millisUntilFinished / 10000 == 0){ //TEN SECONDS
Log.v(TAG, (millisUntilFinished % 1000) + " seconds left");
}
}
#Override
public void onFinish() {
Log.v(TAG, "Finished");
Now, I should be getting two different log messages at ten seconds. Instead, I only get one. Here is my logCat:
The arrow indicates where there should have been another log message.
I am lost. I would really appreciate any feedback (positive or negative)! Thank you so much for all of your help.
As you said yourself, you could launch both services at the same time.
Or inside the first service, you could pass an Intent with some parameters to inform the new amount of time and then call startService().
Intent it = new Intent(getApplicationContext(), YourService.class);
it.putExtra("Time", timeInMillis);
startService(it);
I mean, modify your Service to get an extra from the calling Intent, something like this:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
long time = intent.getLongExtra("Time",0);
// Do your ticking here, based on that variable.
}
//...
}
Edit: Let's say you want to make your timer run first at 5 seconds, then at 10, 15, and so on.
Once you finish your timer, you could pass the Intent to the new Service/Timer adding the seconds you want. Like:
it.putExtra("Time", timeInMillis + 5000);
Use this type.
cdt = new CountDownTimer(10000, 1000) { //finished on 10 Seconds
#Override
public void onTick(long millisUntilFinished) {
Log.v(TAG, /*"Time remaining " +*/ (millisUntilFinished / 1000) + " seconds left");
}
#Override
public void onFinish() {
Log.v(TAG, "First 10 Seconds Finished");
LoadNextCountdown(); // call the Next Countdown method
}
}
.start();
//Method for Next Countdown
public void LoadNextCountdown()
{
cdt2=new CountDownTimer(10000,1000) { //finished on 10 Seconds
#Override
public void onTick ( long millisUntilFinished){
Log.v(TAG, /*"Time remaining " +*/ (millisUntilFinished / 1000) + " seconds left");
}
#Override
public void onFinish () {
Log.v(TAG, "Next 10 Seconds Finished");
}
} .start();
}
Happy Coding :)
Your log is not displaying because:
if(millisUntilFinished / 10000 == 0){ //TEN SECONDS
Log.v(TAG, (millisUntilFinished % 1000) + " seconds left");
}
you want it to display when you have 10000 millisUntilFinished but 10000/10000 = 1 not 0.
it should be:
if(millisUntilFinished / 10000 == 1) || if(millisUntilFinished % 10000 == 0)
or simply:
if(millisUntilFinished == 10000)
In this code a while loop is supposed to check the time, and if the time is equal to 7 PM, then display a message box.
public void actionPerformed(ActionEvent arg0) {
Enable.setEnabled(false);
Date d = new Date();
int hrs = d.getHours();
int mins = d.getMinutes();
while((1 + 1) == 2) {
if(hrs == 19 && mins == 21) {
JOptionPane.showMessageDialog(frame,
"It's 7:21 PM!",
"Alerts",
JOptionPane.WARNING_MESSAGE);
System.exit(0);
break;
}
}
}
Pushing a button will do that code. If you push the button before it is 7 PM, the GUI will freeze (I don't care about that), and when it turns to 7 PM, it won't display the message box. If you click the button when it is 7 PM, then it will display the message box...
Instead of doing while((1 + 1) == 2) to get an infinite loop, you can just do: while(true) or for(;;)
And this question is unanswerable without any further information or code about your hrs and mins variables
You need to update hrs and mins in your loop otherwise the initialization of them, I assume at the time of pushing the button will always hold the time when the button was pushed.
This is why it works when pushed at 7pm but otherwise will not.
So do something like this
while(true) //Equivalent to what you had
{
if(hrs == 19 && mins == 00) {
JOptionPane.showMessageDialog(frame,
"It's 7:00 PM!",
"Time Alert",
JOptionPane.WARNING_MESSAGE);
System.exit(0);
break;
}
//Refresh your hrs and mins here
Calendar calendar = GregorianCalendar.getInstance(); // Probably dont really want to actually get an instance every time
hrs = calendar.get(Calendar.HOUR_OF_DAY);
mins = calendar.get(Calendar.MINUTE);
}
I'm thinking you're using 1+1=2 to have a continuous loop. you could use while(true){...} instead.
Also, the while loop wouldn't be practical for this case. There is an example on this page that does something similar (Alarm Clock): http://www.ibm.com/developerworks/java/library/j-schedule/index.html
this was their example. I updated it to suite your task.
public class AlarmClock {
private final Scheduler scheduler = new Scheduler();
private final SimpleDateFormat dateFormat =
new SimpleDateFormat("dd MMM yyyy HH:mm:ss.SSS");
private final int hourOfDay, minute, second;
public AlarmClock() {
this.hourOfDay = 19;
this.minute = 0;
this.second = 0;
}
public void start() {
scheduler.schedule(new SchedulerTask() {
public void run() {
soundAlarm();
}
private void soundAlarm() {
JOptionPane.showMessageDialog(frame,
"It's 7:00 PM!",
"Time Alert",
JOptionPane.WARNING_MESSAGE);
System.exit(0);
// Start a new thread to sound an alarm...
}
}, new DailyIterator(hourOfDay, minute, second));
}
public static void main(String[] args) {
AlarmClock alarmClock = new AlarmClock();
alarmClock.start();
}
}
Hope it helps.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I found this stopwatch java code from somewhere on the Internet, but it does not seem to be working. I was wondering how to fix this code to make it work. It's supposed to have features to start, stop and reset, and should display the time as hours:minutes:seconds.milliseconds (example: 12:35:17.26). Please help me.
public class StopWatch {
private long startTime = 0;
private long stopTime = 0;
private boolean running = false;
public void start() {
this.startTime = System.currentTimeMillis();
this.running = true;
}
public void stop() {
this.stopTime = System.currentTimeMillis();
this.running = false;
}
//elaspsed time in milliseconds
public long getElapsedTime() {
long elapsed;
if (running) {
elapsed = (System.currentTimeMillis() - startTime);
}
else {
elapsed = (stopTime - startTime);
}
return elapsed;
}
//elaspsed time in seconds
public long getElapsedTimeSecs() {
long elapsed;
if (running) {
elapsed = ((System.currentTimeMillis() - startTime) / 1000);
}
else {
elapsed = ((stopTime - startTime) / 1000);
}
return elapsed;
}
//sample usage
public static void main(String[] args) {
StopWatch s = new StopWatch();
s.start();
//code you want to time goes here
s.stop();
System.out.println("elapsed time in milliseconds: " + s.getElapsedTime());
}
}
This example shows how to start and stop a javax.swing.Timer. Several approaches to formatting are shown here. Reset is left as an exercise.
By the level of your assignment, sounds like your professor wants you to use nested loops, which are not being used in the example you took from the web.
I won't give you the full answer, but it's fairly simple: outer-most loop is for hours, the one inside hours is for minutes, the one inside minutes for seconds, and the one inside seconds for milliseconds. The inner-most loop (milliseconds), is the one that prints the current time.
Something like this:
// 24 hours in a day
for(int hours = 0; hours < 24; hours++)
{
// 60 mins in an hours
for(int minutes = 0; minutes < 60; minutes++)
{
// 60 secs in a min
for(int seconds = 0; seconds < 60; seconds++)
{
// 1000 ms in a sec.
for(int ms = 0; ms < 1000; ms++)
{
System.out.println(hours + ":" + minutes + ":" + seconds + "." + ms);
}
}
}
}
Now make it pretty and add a 1-millisecond delay in the inner-most loop and you are done! :)
If you want to make a stopwatch you must make a Thread. The Java API states all of the functions of a thread. This is necessary, because otherwise you won't be able to pause the timer. This is because the system spends the full runtime on the counting.
Also, the script you provided is used for determining the amount of time a certain calculation took, it's not ment for timing itself.
I suggest you make 2 classes, 1 for the timer and 1 for the GUI. make the GUI with a label, a start-, stop- and reset-button.
Next, make sure the timer-class EXTENDS THREAD (or implements Runnable) and make it a thread. Next implement the functions to either stop the thread or start the thread (your start/stop buttons). The Reset should be easy after that (just set the timer back to 0).
The StopWatch-class could look like this:
public class Stopwatch extends Thread
{
private long startTime;
private boolean started;
public void startThread()
{
this.startTime = System.currentTimeMillis();
this.started = true;
this.start();
}
public void run()
{
while (started)
{
// empty code since currentTimeMillis increases by itself
}
}
public int[] getTime()
{
long milliTime = System.currentTimeMillis() - this.startTime;
int[] out = new int[]{0, 0, 0, 0};
out[0] = (int)(milliTime / 3600000 );
out[1] = (int)(milliTime / 60000 ) % 60;
out[2] = (int)(milliTime / 1000 ) % 60;
out[3] = (int)(milliTime) % 1000;
return out;
}
public void stopThread()
{
this.started = false;
}
}
In the GUI-class you would make start call the 'startThread', stop call the StopWatch.stop(); (which is a Thread-function) and make reset call the reset().
This should get you started with a basic stopwatch. A (bad) example for its useage:
public static void main(String[] args) throws InterruptedException
{
Stopwatch s = new Stopwatch();
s.startThread();
while (true)
{
int[] curTime = s.getTime();
System.out.println(curTime[0] + " : " + curTime[1] + " : " + curTime[2] + " : " + curTime[3]);
}
}
It would actually be more sensible to do the calculations on the currentTimeMillis outside of the threadclass.