I have this code
public void LoadCurrentTime(long time_last) {
long millis_now = System.currentTimeMillis();
long time_till = millis_now - time_last;
String showTime;
int showHours, showMin, showSec;
if (time_till > 604800000) {
showTime = getString(R.string.long_ago);
} else {
//long longHours = (time_till / 1000 / 60 / 60);
//long longMin = (time_till / 1000 / 60 % 60);
//long longSec = (time_till / 1000 % 60);
//showHours = (int) longHours;
//showMin = (int) longMin;
//showSec = (int) longSec;
//showTime = String.format("%02d", showHours) + ":" + String.format("%02d", showMin) + ":" + String.format("%02d", showSec);
// v1.0^
long longsec = (time_till / 1000) % 60;
long longmin = (time_till / (1000 * 60)) % 60;
long longhours = (time_till / (1000 * 60 * 60)) % 24;
showHours = (int) longhours;
showMin = (int) longmin;
showSec = (int) longsec;
showTime = String.format("%02d", showHours) + ":" + String.format("%02d", showMin) + ":" + String.format("%02d", showSec);
}
TextView lastTime = findViewById(R.id.textView4);
I want to update a TextView content every second and show a notification, but the TextView update and the notification show only when open the app, so
How can I update the TextView and show notification every one second in background?
You can user Timer and TimerTask to for recurring tasks. Don't forget to call timer.cancel() at end of the program.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Call your method
LoadCurrentTime()
}
},0, 2000);
I have one countdown timer in my activity.
In which I have converted Mins into Millisecond.
Based on that Millisecond, I have managed to counter HH: mm: ss using CountDownTimer.
So, I want a difference between main time and remaining time.
For example, My main time is 00:10:00 and when I stop counter suppose my remaining time is 00:07:30. means I spend 2:30 seconds
An expected result I want is 150seconds.
Example Code:
public class MainActivity extends AppCompatActivity {
int duration;
TextView textView;
ProgressBar progressbar;
Button btn_stop, btn_resume;
CountDownTimer counter;
int i = 1;
int remainingDuration;
int countDownInterval = 1000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.tvSampleText);
progressbar = (ProgressBar) findViewById(R.id.progressbar);
btn_stop = (Button) findViewById(R.id.btn_stop);
btn_resume = (Button) findViewById(R.id.btn_resume);
// duration=81200000; //6 hours
duration = (int) TimeUnit.MINUTES.toMillis(1);
counter = new MyCount(duration, countDownInterval);
counter.start();
btn_stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
counter.cancel();
}
});
btn_resume.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
counter = new MyCount(remainingDuration, countDownInterval);
counter.start();
}
});
}
public class MyCount extends CountDownTimer {
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
textView.setText("00:00:00");
}
#Override
public void onTick(long millisUntilFinished) {
i++;
long secondsInMilli = 1000;
long minutesInMilli = secondsInMilli * 60;
long hoursInMilli = minutesInMilli * 60;
long elapsedHours = millisUntilFinished / hoursInMilli;
millisUntilFinished = millisUntilFinished % hoursInMilli;
long elapsedMinutes = millisUntilFinished / minutesInMilli;
millisUntilFinished = millisUntilFinished % minutesInMilli;
long elapsedSeconds = millisUntilFinished / secondsInMilli;
String yy = String.format("%02d:%02d:%02d", elapsedHours, elapsedMinutes, elapsedSeconds);
textView.setText(yy);
progressbar.setProgress((int) i * 100 / (duration / (int) secondsInMilli));
remainingDuration = (int) millisUntilFinished;
}
}
}
First convert the minutes duration into seconds
long secs = minutes * 60; 10 * 60 = 600
and inside on tick, you get the remaining time in milliseconds so keep the value as global reference and convert it into seconds as
long mMillisUntilFinished;
void onTick (long millisUntilFinished){
// mMillisUntilFinished = 450000
mMillisUntilFinished = millisUntilFinished;
}
then when you press stop then get the renaming time difference as
long diffSeconds = secs - (mMillisUntilFinished / 1000)
// 600 - (450000 /1000)
// 600 - 450
// 150
update: As suggested, calculate the seconds for both duration and left time then subtract them to get the result.
Use long instead of int casting
#Override
public void onTick(long millisUntilFinished) {
i++;
long secondsInMilli = 1000;
long minutesInMilli = secondsInMilli * 60;
long hoursInMilli = minutesInMilli * 60;
long tempMili = millisUntilFinished;
long elapsedHours = tempMili / hoursInMilli;
tempMili = tempMili % hoursInMilli;
long elapsedMinutes = tempMili / minutesInMilli;
tempMili = tempMili % minutesInMilli;
long elapsedSeconds = tempMili / secondsInMilli;
String yy = String.format("%02d:%02d:%02d", elapsedHours, elapsedMinutes, elapsedSeconds);
textView.setText(yy);
progressbar.setProgress((int) i * 100 / (duration / (int) secondsInMilli));
remainingDuration = (duration/ 1000) - (millisUntilFinished/1000);
}
I have a basic Timer in my app:
TextView timerTextView = (TextView) findViewById(R.id.timer);
long startTime = 0;
Handler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000) * 1;
int minutes = seconds / 60;
seconds = seconds % 60;
timerTextView.setText(String.format("%02d:%02d", minutes, seconds));
timerHandler.postDelayed(this, 500);
if (minutes == 45 && seconds == 0) {
addHeader("2nd Half");
}
}
};
addHeader() method:
private void addHeader(String header) {
TableLayout table = (TableLayout) findViewById(R.id.myTable);
TableRow tr = new TableRow(this);
tr.setLayoutParams(...);
TextView textView = new TextView(this);
textView.setLayoutParams(..);
textView.setText(header);
// more code
tr.addView(textView);
table.addView(tr);
}
onCreate():
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startTimer();
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
}
When my timer reaches 45:00 a new row is added to my TableLayout multiple times. I've created an alternative solution but I'd like to know what I'm missing.
if (!isAdded) {
addHeader("2nd Half");
isAdded = true;
}
A good way to check what is going on is to log every time the Handler is run and every time addHeader fires
e.g:
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000) * 1;
int minutes = seconds / 60;
seconds = seconds % 60;
millis = millis % 1000;
timerTextView.setText(String.format("%02d:%02d", minutes, seconds));
Log.d("MainActivity", String.format(Locale.ENGLISH,"Checking time: %02d:%02d:%03d" , minutes, seconds, millis));
timerHandler.postDelayed(this, 500);
if (minutes == 45 && seconds == 0) {
Log.d("MainActivity", String.format(Locale.ENGLISH,"2nd Half: %02d:%02d:%03d" , minutes, seconds, millis));
addHeader("2nd Half");
}
}
Doing this you will see that addHeader is called twice. This is because every 500ms your Handler is running, checking the difference between the current time and start time, in minutes and seconds (ignoring ms). To fix the issue try changing
timerHandler.postDelayed(this, 500);
to
timerHandler.postDelayed(this, 1000);
I am passing two different times into two different objects and the time is always the same. Any suggestions as to what I should do?
public class TwoTimeClock extends JFrame {
Clock clockFace;
Clock clockFacetwo;
public static void main(String[] args) {
JFrame windo = new TwoTimeClock();
windo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
windo.setVisible(true);
}
private final Clock clockFaceTwo;
/**
* empty constructor. initializes instance variables, draws the clocks,
* and starts them
*/
public TwoTimeClock() {
Container content = this.getContentPane();
content.setLayout(new BorderLayout());
Time time1 = new Time();
Time time2 = new Time();
clockFace = new Clock(time1);
clockFaceTwo = new Clock(time2);
content.add(clockFace, BorderLayout.WEST); //BorderLayout.WEST and BorderLayout.EAST decide the clocks lie in the left or right of box
//hint if you add another clockFace to the content object above, then the canvas will grow in size
content.add(clockFaceTwo, BorderLayout.EAST);
this.setTitle("Baltimore New Delhi");
this.pack();
clockFace.start();
time2.setHrsOffset(9);
time2.setMinsOffset(30);
clockFaceTwo.start();
}
}
Time time;
private static final int spacing = 10;
private static final float threePi = (float) (3.0 * Math.PI);
// Angles for the trigonometric functions are measured in radians.
// The following in the number of radians per sec or min.
private static final float radPerSecMin = (float) (Math.PI / 30.0);
private int size; // height and width of clock face
private int centerX; // x coord of middle of clock
private int centerY; // y coord of middle of clock
private BufferedImage clockImage;
private javax.swing.Timer t;
/**
* //>>>>>>>>>>>>>>>>> You should modify this constructor to take an object of Time class as parameter
* Constructor. Takes an object of the Time class that it will use for showing the time
* #param
*/
public Clock(Time t1) {
this.time = t1;
this.setPreferredSize(new Dimension(300, 300));
this.setBackground(Color.white);
this.setForeground(Color.black);
t = new javax.swing.Timer(1000,
new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
update();
}
});
}
/**
* Replace the default update so that the plain background doesn't get drawn.
*/
public void update() {
this.repaint();
}
public void start() {
t.start(); // start the timer
}
public void stop() {
t.stop(); // stop the timer
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g); // paint background, borders
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// The panel may have been resized, get current dimensions
int w = getWidth();
int h = getHeight();
size = ((w < h) ? w : h) - 2 * spacing;
size -= 50; //reducing size to make space for text below clock face
centerX = size / 2 + spacing;
centerY = size / 2 + spacing;
// Create the clock face background image if this is the first time,
// or if the size of the panel has changed
if (clockImage == null
|| clockImage.getWidth() != w
|| clockImage.getHeight() != h) {
clockImage = (BufferedImage) (this.createImage(w, h));
// now get a graphics context from this image
Graphics2D gc = clockImage.createGraphics();
gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
drawClockFace(gc);
}
time.update();
time.updateOffSet();
//>>>>>>>>>>>>>>>>>>>>>>>
// Draw the clock face from the precomputed image
g2.drawImage(clockImage, null, 0, 0);
// Draw the clock hands
drawClockHands(g);
//Print Clock
g2.drawString(Time.toStandard(), 90, h-15);
g2.drawString(Time.toMilitary(), 90, h-30);
}
/**
* The hour, minute, and second hand
* #param g
*/
private void drawClockHands(Graphics g) {
int secondRadius = size / 2;
int minuteRadius = secondRadius * 3 / 4;
int hourRadius = secondRadius / 2;
// second hand
float fseconds = time.getSecs() + (float) time.getMillis()/ 1000;
float secondAngle = threePi - (radPerSecMin * fseconds);
drawRadius(g, centerX, centerY, secondAngle, 0, secondRadius);
// minute hand clock 1
float fminutes = (float) (time.getMins() + fseconds / 60.0);
float minuteAngle = threePi - (radPerSecMin * fminutes);
drawRadius(g, centerX, centerY, minuteAngle, 0, minuteRadius);
// hour hand clock 1
float fhours = (float) (time.getHrs() + fminutes / 60.0);
float hourAngle = threePi - (5 * radPerSecMin * fhours);
drawRadius(g, centerX, centerY, hourAngle, 0, hourRadius);
}
private void drawClockFace(Graphics g) {
// clock face
g.setColor(Color.lightGray);
g.fillOval(spacing, spacing, size, size);
g.setColor(Color.black);
g.drawOval(spacing, spacing, size, size);
// tic marks
for (int sec = 0; sec < 60; sec++) {
int ticStart;
if (sec % 5 == 0) {
ticStart = size / 2 - 10;
} else {
ticStart = size / 2 - 5;
}
drawRadius(g, centerX, centerY, radPerSecMin * sec, ticStart, size / 2);
}
}
private void drawRadius(Graphics g, int x, int y, double angle,
int minRadius, int maxRadius) {
float sine = (float) Math.sin(angle);
float cosine = (float) Math.cos(angle);
int dxmin = (int) (minRadius * sine);
int dymin = (int) (minRadius * cosine);
int dxmax = (int) (maxRadius * sine);
int dymax = (int) (maxRadius * cosine);
g.drawLine(x + dxmin, y + dymin, x + dxmax, y + dymax);
}
}
public class Time {
private static int hrs = 00;
private static int mins = 00;
private static int secs = 00;
private static int millis = 00;
static int copyHrs;
static int copyMins;
static int copySecs;
static int hrsOffset;
static int minsOffset = 30;
//Empty Constructor
public Time() {
Calendar t1 = Calendar.getInstance();
hrs = t1.get(Calendar.HOUR);
mins = t1.get(Calendar.MINUTE);
secs = t1.get(Calendar.SECOND);
millis = t1.get(Calendar.MILLISECOND);
}
//Alternate Constructor
public Time(int hours, int minutes, int seconds, int millisec) {
hrs = hours;
mins = minutes;
secs = seconds;
millis = millisec;
}
//Copy Constructor
public Time(Time otherClock) {
copyHrs = hrs;
copyMins = mins;
copySecs = secs;
millis = millis;
}
public int getHrs() {
return hrs;
}
public void setHrs(int hrs) {
this.hrs = hrs;
}
public int getMins() {
return mins;
}
public void setMins(int mins) {
this.mins = mins;
}
public int getSecs() {
return secs;
}
public void setSecs(int secs) {
this.secs = secs;
}
public int getMillis() {
return millis;
}
public void setMillis(int millis) {
this.millis = millis;
}
public static int getHrsOffset() {
return hrsOffset;
}
public void setHrsOffset(int hrsOffset) {
this.hrsOffset = hrsOffset;
}
public void printOffset(Time clock, int hrsOffset, int minsOffset) {
hrs = Math.abs(clock.hrs + hrsOffset);
mins = Math.abs(clock.mins + minsOffset);
secs = clock.secs;
if (hrs < 12) {
System.out.printf("%02d:%02d:%02d AM%n", hrs, mins, secs);
} else if (hrs == 24) {
System.out.printf("12:%02d:%02d AM%n", mins, secs);
} else if (hrs == 12) {
System.out.printf("12:%02d:%02d PM%n", mins, secs);
} else {
System.out.printf("%02d:%02d:%02d PM%n", hrs - 12, mins, secs);
}
}
public static int getMinsOffset() {
return minsOffset;
}
public void setMinsOffset(int minsOffset) {
this.minsOffset = minsOffset;
}
public static void printMilitary() {
hrs = hrs % 24;
System.out.printf("%02d:%02d:%02d %n", hrs, mins, secs);
}
public static void printStandard() {
hrs = hrs % 24;
if (hrs < 12) {
System.out.printf("%02d:%02d:%02d AM%n", hrs, mins, secs);
} else if (hrs == 24) {
System.out.printf("12:%02d:%02d AM%n", mins, secs);
} else if (hrs == 12) {
System.out.printf("12:%02d:%02d PM%n", mins, secs);
} else {
System.out.printf("%02d:%02d:%02d PM%n", hrs - 12, mins, secs);
}
}
#Override
public String toString() {
return hrs + ":" + mins + ":" + secs;
}
public boolean equals(Time otherClock) {
if (hrs == otherClock.hrs && mins == otherClock.mins && secs == otherClock.secs) {
return true;
} else {
return false;
}
}
public static int getCopy() {
copyHrs = Time.hrs;
copyMins = Time.mins;
copySecs = Time.secs;
return copyHrs + copyMins + copySecs;
}
public static void advanceSecs() {
secs++;
if (secs > 59) {
mins++;
secs = 00;
}
if (mins > 59) {
hrs++;
secs = 00;
mins = 00;
}
}
public boolean lessThan(Time otherClock) {
if ((hrs < otherClock.hrs) && (mins < otherClock.mins) && (secs < otherClock.secs)) {
return true;
} else {
return false;
}
}
public boolean notEquals(Time otherClock) {
if ((hrs == otherClock.hrs) && (mins == otherClock.mins) && (secs == otherClock.secs)) {
return true;
} else {
return false;
}
}
public boolean lessOrEquals(Time otherClock) {
if ((hrs <= otherClock.hrs) && (mins <= otherClock.mins) && (secs <= otherClock.secs)) {
return true;
} else {
return false;
}
}
public boolean greaterThan(Time otherClock) {
if ((hrs > otherClock.hrs) && (mins > otherClock.mins) && (secs > otherClock.secs)) {
return true;
} else {
return false;
}
}
public static String toMilitary() {
hrs = hrs%24;
String str = String.format("%02d:%02d:%02d", hrs, mins, secs);
return str;
}
public static String toStandard() {
String str = String.format("%02d:%02d:%02d PM", hrs, mins, secs);
if (hrs > 12) {
hrs = hrs - 12;
str = String.format("%02d:%02d:%02d AM", hrs, mins, secs);
} else if (hrs == 12) {
str = String.format("%02d:%02d:%02d AM", hrs, mins, secs);
}
return str;
}
public void update() {
Calendar t1 = Calendar.getInstance();
hrs = t1.get(Calendar.HOUR);
mins = t1.get(Calendar.MINUTE);
secs = t1.get(Calendar.SECOND);
millis = t1.get(Calendar.MILLISECOND);
}
public void updateOffSet() {
Calendar t1 = Calendar.getInstance();
hrs = t1.get(Calendar.HOUR) + hrsOffset;
mins = t1.get(Calendar.MINUTE) + minsOffset;
secs = t1.get(Calendar.SECOND);
millis = t1.get(Calendar.MILLISECOND);
}
}
You've got nothing but static fields in Time, and this will guarantee that Time instances will all share the same state. Don't do this. Make those fields instance (i.e., non-static) fields.
Also, your Time copy constructor doesn't, and in fact completely ignores the otherClock parameter that passes into it.
Your Time class should not have the copyHrs, copyMins, etc... fields as they serve no useful purpose.
Your getCopy() method is a bit absurd. What use is adding all the mins, hours, and seconds together? The number has no meaning. Shouldn't that method return a Time instance, one with the same state as the current Time instance?
Here is what I have so far
long startTime = 0;
TextView timerTextView;
final Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
#Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) millis / 1000;
int minutes = (int) seconds / 60;
seconds %= 60;
int min = 40000;
int max = 49999;
long randomTime = (long) (Math.random()*(min-max) + max);
timerTextView.setText(minutes + ":" + seconds);
timerHandler.postDelayed(this, 500);
}
};
I want to know how I can use the randomTime variable to trigger my TextView to change to say Time Is Up. I found a way to create a scheduled task using the following:
timerHandler.postAtTime(Runnable r, randomTime);
The only problem is I don't know what Runnable I should use to cause the TextView to change.
First of all put the randomTime outside of the thread,
int min = 40000;
int max = 49999;
long randomTime = (long) (Math.random()*(min-max) + max);
Create a simple handler that'll run after the time specified by randomTime variable,
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// handler has reached the time
// now update the TextView using a runOnUiThread
runOnUiThread(new Runnable() {
public void run() {
// Update UI elements
// get the current time now
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) millis / 1000;
int minutes = (int) seconds / 60;
seconds %= 60;
//finally update the TextView
timerTextView.setText(minutes + ":" + seconds);
}
});
}
}, randomTime);