Problems with Chronometer and ViewModel - java

Pressing the button changes the chronometerStateLData and the Chronometer starts, after turning the screen Observer executes the code again, but the Chronometer does not start.
viewModel.chronometerStateLData.observe(viewLifecycleOwner, Observer {
Utils.setSettingChronometer(binding.timerRecord)
binding.timerRecord.start()
})
public static void setSettingChronometer(Chronometer chronometer) {
chronometer.setOnChronometerTickListener(chronometer1 -> {
long time = SystemClock.elapsedRealtime() - chronometer1.getBase();
int h = (int) (time / 3600000);
int m = (int) (time - h * 3600000) / 60000;
int s = (int) (time - h * 3600000 - m * 60000) / 1000;
String t = (h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s);
chronometer1.setText(t);
});
}

I solved my problem. I didn't check if (savedInstanceState == null) when I created my fragment, so every time I flipped the screen a new fragment was created.

Related

Stopwatch with sound at a certain time

I have a project that contains a timer, I'm trying to put an alarm or music to play when the time of 12 minutes is reached. How could this be possible? If anyone can help me, I'm a beginner.
Buttons that start, pause, and reset the timer
switch (view.getId()) {
case R.id.bt_control:
if (btControl.getText().equals("Play")) {
this.startService(intent);
cmPasstime.setBase(SystemClock.elapsedRealtime());
cmPasstime.start();
btControl.setText("Stop");
} else if (btControl.getText().equals("Stop")) {
this.stopService(intent);
cmPasstime.stop();
btControl.setText("Play");
} else if (btControl.getText().equals("Play")) {
this.startService(intent);
cmPasstime.start();
btControl.setText("Stop");
}
break;
case R.id.bt_reset:
reset();
break;
}
Stopwatch
#Override
public void onChronometerTick(Chronometer arg0) {
seconds++;
cmPasstime.setText(formatseconds());
}
public String formatseconds() {
String hh = seconds / 3600 > 9 ? seconds / 3600 + "" : "0" + seconds
/ 3600;
String mm = (seconds % 3600) / 60 > 9 ? (seconds % 3600) / 60 + ""
: "0" + (seconds % 3600) / 60;
String ss = (seconds % 3600) % 60 > 9 ? (seconds % 3600) % 60 + ""
: "0" + (seconds % 3600) % 60;
return hh + " : " + mm + " : " + ss;
}
Reset
private void reset() {
tvPasstime.setText("00:00:00");
cmPasstime.setBase(SystemClock.elapsedRealtime());
cmPasstime.stop();
btControl.setText("Play");
}
Try to use Firebase JobDispatcher, this library will schedule job in background to do something at specified time.
https://github.com/firebase/firebase-jobdispatcher-android

Missing Return Statement

I am trying to write code which would, given the time of day in terms of an hour, minute, second and "day half" (i.e., AM or PM), calculate and return the fraction of the day (a value of type double) that has elapsed since midnight (12:00 AM).
For example,
System.out.print(fractionOfDay(12, 0, 0, 'A'));
would print 0.0
System.out.print(fractionOfDay(12, 0, 0, 'P'));
would print 0.5
System.out.print(fractionOfDay(11, 59, 59, 'P'));
would print 0.999988426
I have written the following code:
public class FractionOfDay {
public static double fractionOfDay(double h, double m, int s, char a ) {
if (a == 'P' && h == 12) {
double x = (h * 60 * 60) + (m * 60) + (s);
double y = x / 86400;
return y;
} else if (a == 'P' && h != 12) {
double x = ( (h + 12) * 60 * 60) + (m * 60) + (s);
double y = x / 86400;
return y;
} else if (a == 'A' && h == 12) {
double x = (m * 60) + (s);
double y = x / 86400;
} else if (a == 'A' && h != 12) {
double x = ( (h) * 60 * 60) + (m * 60) + (s);
double y = x / 86400;
return y;
}
}
public static void main(String[] args) {
System.out.println(fractionOfDay(12, 0, 0, 'P'));
}
}
However, when I try to compile this code, it gives me the error
missing return statement.
I don't understand what is wrong with the code.
That's because all of your return statements are within if statements. Java sees this and judges that there is a possibility that none of these if statements will be taken. Then what would happen? There would be no return, so it spits out an error.
So you need to add a return statement under an else clause or outside of the if/else if block entirely. Something like this will solve your problem. You would have to figure out what to do when none of your paths gets taken. In this case it will return -1 (the default value of y)
public class FractionOfDay {
public static double fractionOfDay(double h, double m, int s, char a ) {
double y = -1;
if (a == 'P' && h == 12) {
double x = (h * 60 * 60) + (m * 60) + (s);
y = x / 86400;
} else if (a == 'P' && h != 12) {
double x = ( (h + 12) * 60 * 60) + (m * 60) + (s);
y = x / 86400;
} else if (a == 'A' && h == 12) {
double x = (m * 60) + (s);
y = x / 86400;
} else if (a == 'A' && h != 12) {
double x = ( (h) * 60 * 60) + (m * 60) + (s);
y = x / 86400;
}
return y;
}
public static void main(String[] args) {
System.out.println(fractionOfDay(12, 0, 0, 'P'));
}
}
The code doesn't tell you what to do in the case where a is something other than 'A' or 'P'. Maybe you know it will never be anything else, but the compiler doesn't know that, so it believes there's a possibility that the code might hit the end of the method without returning anything, which is a no-no.
Since this is a public method, you really ought to have your code do something with cases when the arguments don't fit into one of your cases, since an outside class could screw up and call it with the wrong thing. The obvious solution is to put a throw at the end of the method, something like
throw new RuntimeException("Invalid arguments to fractionOfDay");
This will prevent the error message from occurring.

Converting seconds to hours, minutes and seconds

I want to use count up timer in android for long hours...
Currently, I am using this code, but after some hours, say after 10 hours, the format goes like 10 : 650 :56 (hh:mm:ss)... for lesser time, it works perfectly...
private Runnable updateTimerMethod = new Runnable() {
public void run() {
timeInMillies = SystemClock.uptimeMillis() - startTime;
finalTime = timeSwap + timeInMillies;
int seconds = (int) (finalTime / 1000);
int minutes = seconds / 60;
int hours = minutes / 60;
seconds = seconds % 60;
int milliseconds = (int) (finalTime % 1000);
String timer = ("" + String.format("%02d", hours) + " : "
+ String.format("%02d", minutes) + " : "
+ String.format("%02d", seconds));
myHandler.postDelayed(this, 0);
sendLocalBroadcast(timer);
}
};
Your code for minutes is almost right, but you have to modulus it by 60 just like you do for seconds. Otherwise your value is going to still include all the hours.
Use this function:
private static String timeConversion(int totalSeconds) {
final int MINUTES_IN_AN_HOUR = 60;
final int SECONDS_IN_A_MINUTE = 60;
int seconds = totalSeconds % SECONDS_IN_A_MINUTE;
int totalMinutes = totalSeconds / SECONDS_IN_A_MINUTE;
int minutes = totalMinutes % MINUTES_IN_AN_HOUR;
int hours = totalMinutes / MINUTES_IN_AN_HOUR;
return hours + " : " + minutes + " : " + seconds;
}
You can found other solution in:
https://codereview.stackexchange.com/q/62713/69166

Calculation of times off milliseconds to time

This code below is used to format milliseconds. The calculations are off by a long shot. I need some help with it. Output of my code is below as well as the milliseconds into a Date class.
public static void main(String[] args) {
System.out.println("Wrong Time: " + getTime(999999999 * 599));
}
//Being called into this method is milliseconds = 598999999401
public static String getTime(long miliseconds) {
int years = (int) ((miliseconds / (1000*60*60*24*7*52*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*52) % 12);
int weeks = (int) ((miliseconds / (1000*60*60*24*7)) % 52);
int days = (int) ((miliseconds / (1000*60*60*24)) % 7);
int hours = (int) ((miliseconds / (1000*60*60)) % 24);
int minutes = (int) ((miliseconds / (1000*60)) % 60);
int seconds = (int) (miliseconds / 1000) % 60;
Date date = new Date(598999999401L);//This gets the real time
System.out.println("Right Time: " + date.getYear() + " years " + (int)(date.getMonth() % 12) + " months " + (int)(date.getDay() % 52) + " weeks "
+ (int)(date.getDay() % 7) + " days " + (int)(date.getHours() % 24) + " hours " + (int)(date.getMinutes() % 60) + " minutes " +
+ (int)(date.getSeconds() % 60) + " seconds");
return (years <= 0 ? "" : years + " year" + (years != 1 ? "s" : "")) +
(months <= 0 ? "" : " " + months + " month" + (months != 1 ? "s" : "")) +
(weeks <= 0 ? "" : " " + weeks + " week" + (weeks != 1 ? "s" : "")) +
(days <= 0 ? "" : " " + days + " day" + (days != 1 ? "s" : "")) +
(hours <= 0 ? "" : " " + hours + " hour" + (hours != 1 ? "s" : "")) +
(minutes <= 0 ? "" : " " + minutes + " minute" + (minutes != 1 ? "s" : "")) +
(seconds <= 0 ? "" : " " + seconds + " second" + (seconds != 1 ? "s" : ""));
}
Correct Output(Date class)
Right Time: 88 years 11 months 6 weeks 6 days 14 hours 53 minutes 19 seconds
Wrong Output(My method)
Wrong Time: 1 month 3 weeks 2 days 3 hours 25 minutes 45 seconds
UPDATE 1 (NEW CALCULATIONS)(Still has logic errors):
int years = (int) ((miliseconds / (1000*60*60*24*7*4*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*4) % 12);
int weeks = (int) ((miliseconds / (1000*60*60*24*7)) % 4);
int days = (int) ((miliseconds / (1000*60*60*24)) % 7);
int hours = (int) ((miliseconds / (1000*60*60)) % 24);
int minutes = (int) ((miliseconds / (1000*60)) % 60);
int seconds = (int) (miliseconds / 1000) % 60;
Two issues.
Your code seems to reflect a belief that there are 52 weeks in a month. These are the two lines at fault.
int years = (int) ((miliseconds / (1000*60*60*24*7*52*12)));
int months = (int) (miliseconds / (1000*60*60*24*7*52) % 12);
Also, you're using int where you should be using long. The maximum int number of milliseconds is just under 25 days, so you can never do date/time arithmetic with int.
One problem is int overflow since your main method is using int literals, not longs. Try:
System.out.println("Wrong Time: " + getTime(999999999L * 599L));
Also, don't use magic numbers. Use constants that make sense and that make your code self-commenting:
private static final int MILI_PER_SEC = 1000;
private static final int SEC_PER_MIN = 60;
private static final int MIN_PER_HR = 60;
private static final int HR_PER_DAY = 24;
private static final int DAYS_PER_YR = 365;
and then,
int years = (int) (miliseconds / (MILI_PER_SEC * SEC_PER_MIN * MIN_PER_HR *
HR_PER_DAY * DAYS_PER_YR));
Also, your calculations are all off. You shouldn't be using weeks in the year calculation at all. Use constants, have them make sense. And how do you know that the "correct" result is in fact correct? You are using deprecated code, and Date doesn't use miliseconds the way that you think that it does. It calculates the date relative to January 1, 1970, 00:00:00 GMT as per the Date API.

How to find degree from the latitude value in android?

I have a latitude and longitude values as a double value(37.33168900, -122.03073100).
I want to convert it to the degree value like (37 19' 54 ,48 11' 52 ).
Any Idea? Thanx in advance.
This will give you Strings in degrees, minutes and seconds of arc:
String strLongitude = location.convert(location.getLongitude(), location.FORMAT_SECONDS);
String strLatitude = location.convert(location.getLatitude(), location.FORMAT_SECONDS);
.
use this
public static String getFormattedLocationInDegree(double latitude, double longitude) {
try {
int latSeconds = (int) Math.round(latitude * 3600);
int latDegrees = latSeconds / 3600;
latSeconds = Math.abs(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;
int longSeconds = (int) Math.round(longitude * 3600);
int longDegrees = longSeconds / 3600;
longSeconds = Math.abs(longSeconds % 3600);
int longMinutes = longSeconds / 60;
longSeconds %= 60;
String latDegree = latDegrees >= 0 ? "N" : "S";
String lonDegrees = longDegrees >= 0 ? "E" : "W";
return Math.abs(latDegrees) + "°" + latMinutes + "'" + latSeconds
+ "\"" + latDegree +" "+ Math.abs(longDegrees) + "°" + longMinutes
+ "'" + longSeconds + "\"" + lonDegrees;
} catch (Exception e) {
return ""+ String.format("%8.5f", latitude) + " "
+ String.format("%8.5f", longitude) ;
}
}
Should be some math:
(int)37.33168 => 37
37.33168 % 1 = 0.33168
0.33168 * 60 = 19,905 => 19
19.905 % 1 = 0.905
0.905 * 60 => 54
same with -122 (add 360 if nagative value)
EDIT:
May be there is some API, which I don't know.
Also take a look at the Location class documentation especially at the convert() method as it should do just what you want.
Abi's answer works very well in my location, but produces errors in some others, e.g. "E" instead of "W" on the Western Hemisphere. IMO it should be:
String lonDegrees = longDegrees >= 0 ? "E" : "W";
instead of:
String lonDegrees = latDegrees >= 0 ? "E" : "W";
Another way you can achieve this is using the following function
private String convertCoordinate(double coordinate, boolean isLatitude){
String[] pString = isLatitude ? new String[]{"N", "S"} : new String[]{"E", "W"};
int degree = (int) coordinate;
int minute = (int) (Math.abs(coordinate) * 60) % 60;
int second = (int) (Math.abs(coordinate) * 3600) % 60;
int index = degree < 0 ? 1 : 0;
degree = Math.abs(degree);
return degree + pString[index] + " " + minute + "' " + second + "\"";
}
Based on SO answers i made a code which convert DEG to DMS with FORMAT
example : 40°42′51″ N 74°00′21″ W
example call : getLocationAsDMS(location,8)
8 is the right number for this format
public String getLocationAsDMS (Location location, int decimalPlace){
String strLatitude = Location.convert(location.getLatitude(), Location.FORMAT_SECONDS);
strLatitude = replaceDelimiters(strLatitude, decimalPlace);
char latCardinal = location.getLongitude() >= 0 ? 'N' : 'S';
strLatitude = strLatitude + " " + latCardinal;
String strLongitude = Location.convert(location.getLongitude(), Location.FORMAT_SECONDS);
strLongitude = replaceDelimiters(strLongitude, decimalPlace);
char lonCardinal = location.getLongitude() >= 0 ? 'E' : 'W';
strLongitude = strLongitude + " " + lonCardinal;
return strLatitude + " " + strLongitude;
}
#NonNull
private String replaceDelimiters(String str, int decimalPlace) {
str = str.replaceFirst(":", "°");
str = str.replaceFirst(":", "'");
int pointIndex = str.indexOf(".");
int endIndex = pointIndex + 1 + decimalPlace;
if(endIndex < str.length()) {
str = str.substring(0, endIndex);
}
str = str + "\"";
return str;
}

Categories