How to display Time in appropriate way ( Min:Sec)? - android

I'm coding a media player app but the Time (for seekbar) appears incorrectly. Is there an error in calculation? How can I adjust the Time in the code?
private void updateSeekBar() {
seekBar.setProgress((int)(((float)mediaPlayer.getCurrentPosition() / mediaFileLength)*100));
if(mediaPlayer.isPlaying())
{
Runnable updater = new Runnable() {
#Override
public void run() {
updateSeekBar();
realtimeLength-=1000; // declare 1 second
textView.setText(String.format("%d:%d", TimeUnit.MILLISECONDS.toMinutes(realtimeLength),
TimeUnit.MILLISECONDS.toSeconds(realtimeLength) -
TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes(realtimeLength))));
}
};
handler.postDelayed(updater,1000); // 1 second
}
}

You are calculating the seconds incorrectly. You need to multiply the minutes by 60 and then subtract it from total seconds to get the seconds in this minute.
TimeUnit.MILLISECONDS.toSeconds(realtimeLength) - 60 * TimeUnit.MILLISECONDS.toMinutes(realtimeLength)
This should work.
You should use Debugger to try to debug why your output is incorrect.

Please pass duration in below method & it will give you formatted result back.
long secs = mediaPlayer.getDuration()/1000;
public String makeShortTimeString(final Context context, long secs) {
long hours, mins;
hours = secs / 3600;
secs %= 3600;
mins = secs / 60;
secs %= 60;
String durationFormat = context.getResources().getString(
hours == 0 ? R.string.durationformatshort : R.string.durationformatlong);
return String.format(durationFormat, hours, mins, secs);
}
where durationformatshort = %2$d:%3$02d
and durationformatlong = %1$d:%2$02d:%3$02d

Related

Variable set in SystemClock.uptimeMillis() can't be reset

Beg you pardon I'm a new developer.
I am using SystemClock.uptimeMillis inside of Runnable to make it look like stopwatch. I took the stopwatch source code from google.
Afterwards I make a modification every 30 seconds a variable (named price) will increase.
The weird thing is, when I start over the stopwatch, the price won't return to initial value. I've tried reset the price value in onActivityResult but the stopwatch displayed random numbers. How to make the price variable return to initial value?
Here are my codes:
Handler handler = new Handler();
long startTime = 0L, timeinMilliseconds=0L,timeSwapBuff=0L, updateTime=0L;
int pressCounter = 0;
int price = 3000;
Runnable updateTimerThread = new Runnable() {
#SuppressLint({"DefaultLocale", "SetTextI18n"})
#Override
public void run() {
timeinMilliseconds = SystemClock.uptimeMillis()-startTime;
updateTime = timeSwapBuff+timeinMilliseconds;
int secs = (int)(updateTime/1000);
int mins = secs/60;
int hours = mins/60;
secs%=60;
int milliseconds = (int)(updateTime%1000);
tv_timer.setText(String.format("%2d",hours)+":"+String.format("%2d",mins)+":"+String.format("%2d",secs)+":"
+String.format("%3d",milliseconds));
if (secs % 30 == 0){
price++;
tv_biaya.setText("Rp. "+price+",00");
}
handler.postDelayed(this,0);
}
};
and when the button clicked the method trigger this code
startTime = SystemClock.uptimeMillis();
handler.postDelayed(updateTimerThread,0);
It seems that the Price still increasing because the "price % 30 == 0" logic. My bad. When the stopwatch the secs turn 0 which %30 is also 0. Therefore, it's not go to initial value.
I've changed the logic, that I make a new a new Runnable for price.

Tamgotchi like app day/night cycle

To learn android I'm making a tamagotchi like app. Its food lvl decreases 1 every hour so if you dont feed it for some hours it dies. I also have that between 8pm and 8am its asleep. Only there is a problem. To change its state to sleeping you need to open the app between 8pm and 8am. That gives the following problem:
If you feed it, lets say at 7pm, 1 hour before it sleeps, and you dont open the app between 8pm and 8 am but at 9am the following day he thinks 13 hours have elapsed instead of 1 (he shouldnt count the sleeping hours) Do you guys ahve any tips?
this is the sleepy and decay code
public void checkSleepyTime()
{
c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int daypart = c.get(Calendar.AM_PM);
if (hour >= 20 && daypart == 1)
{
foodButton.setText("ZZzz");
prefs.edit().remove("foodTime").commit();
buddy.setSleeping(true);
}
else
{
foodButton.setText("Awake");
buddy.setSleeping(false);
}
}
.
public void initBuddy()
{
debugView.setText("FoodLevel: " + buddy.getFoodLevel());
if(!buddy.getSleeping() && buddy.getAlive())
{
long currentTime = prefs.getLong("currentTime", getCurentTime());
long foodTime = prefs.getLong("foodTime", getCurentTime());
while (foodTime < currentTime)
{
if (currentTime - foodTime >= ONE_HOUR)
{
buddy.decayFood();
}
foodTime = foodTime + ONE_HOUR;
}
}
If the time since last feeding is longer than sleep time, check if the expected sleep period falls into that time. Then act accordingly (quick hack would be to add the sleep time to the time of last feeding). Also check if more than one day has passed since the feed time. Something like this:
if (currentTime - foodTime >= ONE_HOUR)
{
if (currentTime - foodTime >= WHOLE_NIGHT && sleepPeriodFitsInBetween(foodTime, currentTime))
{
foodTime+=WHOLE_NIGHT;
int numberOfFullDays=countNumberOfDays(currentTime - foodTime);
if(numberOfFullDays>1)
{
currentTime+=numberOfFullDays*(24-WHOLE_HIGHT); // assuming WHOLE_NIGHT is in hours.
}
}
...
}
I now have the following two methods that get the current time and the close time (saved in onStop();) and i converted it to days/weeks/months/years. I want to check how many nights there are between the closeTIme and the currentTIme but I'm not sure what to do with the info. Can anyone point me in the right direction ?
public void checkSleepTimes()
{
closeCalendar = timeHelper.convertLongToCal(loadCloseTime());
closeArray = loadDateArrayList(closeArray, closeCalendar);
currentCalendar = timeHelper.convertLongToCal(getCurentTime());
closeArray = loadDateArrayList(currentArray, currentCalendar);
long curTime = getCurentTime();
int times = 0;
long totalSleepTime = 0;
while (closeTime < curTime)
{
closeTime = closeTime + WHOLE_DAY;
times ++;
}
//TODO Check how many times it was between 08:00 and 20:00
totalSleepTime = SLEEP_TIME * times; // not sure if correct approach
}
public ArrayList loadDateArrayList(ArrayList arrayList, Calendar calendar)
{
arrayList.add(0,calendar.DATE);
arrayList.add(1,calendar.WEEK_OF_YEAR);
arrayList.add(2,calendar.MONTH);
arrayList.add(3,calendar.YEAR);
return arrayList;
}

why countdown counter with thread show wrong value?

I don't know why this count down counter shows a random number at the end?
I mean that it sometimes shows 60:15, sometimes 60:07, so on this way
min=sec=0;
new Thread(new Runnable() {
#Override
public void run() {
while (min < 60 && flagTime) {
try {
Thread.sleep(1);
G.HANDLER.post(new Runnable() {
#Override
public void run() {
String preSec="";
String preMin="";
if (sec < 59) {
sec += 1;
}
if (sec < 10) {
preSec = "0";
}
if (min < 10) {
preMin = "0";
}
score =preMin + min + ":"
+ preSec + sec;
txt[elementNumber + 1].setText(score);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
Please someone tell me why it works so weird?
Timing in ALL OSes is NOT precise, unless you use a framework or tools that is already designed for this task. You can however work with Thread.Sleep with a reasonable uncertainty. But for "reasonable" and "precise" timing, it depends on the problem you are trying to solve.
In threads, sleep(1000) does not mean that the thread will sleep exactly 1 second, so that the thread will sleep less or more every time you run your app. that is why you get random results.
This has many things else to consider like the priority of the thread.
so a better way to count down is to use other ways which is provided by android:
CountDownTimer
Timer
you may check on google and you will find many examples about how to use them.
those are more reliable and more precise.
hope this helps.
The likely reason that you're getting weird results in your TextView is that you're updating it from a thread that is not the main UI thread.
But you're making this harder than it needs to be. An easier approach would be to use a simple CountDownTimer object like this:
final long SECS_IN_1_MIN = 60;
final long MILLIS_IN_1_SEC = 1000;
final long MILLIS_IN_60_MINS = 3600000;
final TextView timer = (TextView) findViewById(R.id.timer);
new CountDownTimer(MILLIS_IN_60_MINS, MILLIS_IN_1_SEC) {
public void onTick(long millisUntilFinished) {
if (flagTime) {
long secs = (MILLIS_IN_60_MINS - millisUntilFinished) / MILLIS_IN_1_SEC;
timer.setText(String.format("%02d:%02d", secs / SECS_IN_1_MIN, secs % SECS_IN_1_MIN));
} else {
timer.setText("cancelled");
cancel();
}
}
public void onFinish() {
timer.setText("time expired");
}
}.start();
Edit: It uses a CountDownTimer to handle the timing, while using its millisUntilFinished value to calculate and display what appears to be an increasing seconds count. I threw in some symbolic names to make the code clearer and a String.format to handle single digit values in a more elegant fashion. Enjoy!

Problems creating timer in android

I am trying to build a timer that counts down in seconds and updates a TextView every time so it shows the time remaining. From what I can tell the timer code is working fine (1 second between events and converts from hrs and mins to secs fine) cause I have tested it outside of Android and using Log.d() in android. Updating the textview is whats giving me problems. I was getting null pointers when originally trying to update the textview cause only the UI thread can access the UI(my interpretation of the error message) and I added the runOnUiThread() which allows it to be accessed and updated but it now doesn't update correctly. I think this is where the problem lies but I am not totally sure and don't know enough to figure out how to fix it or come up with a better way to do this. I would appreciate another set of eyes. Thanks
final static int delay = 1000;
final static int period = 1000;
public void start(int hin, int min) {
run = true;
int hrinsec = (hin * (60 * 60));
int mininsec = (min * 60);
secs = hrinsec + mininsec;
run = false;
interval = secs;
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
// Convert seconds back to hrs and mins
hrsFromSecs(secs);
minsFromSecs(secs);
secsFromSecs(secs);
dint total = hours + minutes + seconds;
output = hours + " Hours " + minutes + " Minutes " + seconds
+ " Seconds";
// Countdown and update the textview
runOnUiThread(new Runnable() {
#Override
public void run() {
timer.setText(output);
}});
secs = secs - 1;
checkIfDone(total);
}
}, delay, period);
}
Use CountDownTimer no need to reinvent anything

Android rolling digital time display wanted

I'm looking for Android code to do a digital timer display that looks like one of the standard timers that came (I think) with some HTC phones. The timer look is different than most in that it uses digits but has a mechanical scroll wheel look, as if the numbers were painted on a roller. It does not mimic an LED timer nor does it mimic a mechanic "flip" type digital timer. It may need graphic files to work.
There is code on googlesource that seems it may have what I want. But I can't find any index that has images of the code running. And it is not always easy (for me) to get the code running so I can see what it looks like. Some code that looks promising is the following:
(https://android.googlesource.com/device/htc/common/)
http://st.gsmarena.com/vv/reviewsimg/htc-droid-incredible-4g-lte/sshots/gsmarena_109.jpg">Link to image</a>">
See http://code.google.com/p/android-wheel/
You might be able to adapt it for your needs.
Here's code provided by a previous user:
private Handler mHandler = new Handler();
OnClickListener mStartListener = new OnClickListener()
{
public void onClick(View v)
{
if (mStartTime == 0L)
{
mStartTime = System.currentTimeMillis();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 100);
}
}
};
.........
private Runnable mUpdateTimeTask = new Runnable()
{
public void run()
{
final long start = mStartTime;
long millis = SystemClock.uptimeMillis() - start;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
if (seconds < 10)
{
mTimeLabel.setText("" + minutes + ":0" + seconds);
}
else
{
mTimeLabel.setText("" + minutes + ":" + seconds);
}
mHandler.postAtTime(this,start + (((minutes * 60) + seconds + 1) * 1000));
}
};
https://stackoverflow.com/users/559090/khawar

Categories

Resources