Android Chronometer - One second "ticks" late - android

The app is a sports timer for cycling, skiing etc, where racers start at regular intervals. e.g. 1 minute.
In my implementation of OnChronometerTickListener I notice that the calls occur at intervals significantly longer than 1000 mS. I use the elapsed time (between the Tick and the Chronometer's base) to count down the last 5 seconds for each interval. Due to the late callback, I can get ticks at, say,
55,500
56,600
57,750
58,870
59,980
61,110
I can therefor skip a whole second when I use m_Elapsed % 1000.
I have even seen the text in the Chronometer get behind and have to skip a second.
I have no problem with accuracy when I do calculations based on the Chronometer's base time and current system time.
Do I have to write my own Chronometer using finer callbacks?
Or is there some other fix?

Related

Countdowntimer works in short intervals, but not others

I am facing an interesting situation, maybe someone could explain to me why.
I am doing timer that runs at interval of 100 msec. At every tick, a textview is updated to show the time. Also there is a an edit text with a text watched in which the string is compared 2 times to different strings After each Text changed
When I use Timer class, then the thread seems to be busy because I can't type any text into the edit text . When I use handler same problem happens. But if I use countdowntimer class then it works.
Interestingly, if I increase the interval to 1 sec then all of the above works.
1-is 100 msec too short? I didint think the above computations I making would take that long.
2- why countdowntimer worked and other failed?
Thank you

Syncing Time in Android

I am trying to sync time between two android devices. The precision has to be upto 5 ms. The gps and network time werent this precise so i thought about sharing time between the devices over the local network and syncing the time using PTP(Precision time protocol).
Now as i can't change the time on non-rooted devices so i thought about saving the time difference shared by device and kept on showing the time to user in a textview.
Now the textview needed to be updated every one ms so the user can see the time in ms too.
I am updating the textview in a thread which is updated every ms.
class CountDownRunner implements Runnable {
// #Override
public void run() {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
while (!Thread.currentThread().isInterrupted()) {
try {
setCurrentTime();
Thread.sleep(1); // Pause of 1/100 Second
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (Exception e) {
}
}
}
}
This is where the problem comes that after syncing the time , the time diff is less then 5 ms but after some time of syncing the time starts to drift a part and after 10-15 mins the time diff is more then 1 sec.
So any ideas on how to rectify this issue?
seems like making thread.sleep(1000) works more like thread.sleep(1003 or 1004) and these changes keep on adding up to make a bigger drift
As I noted, Android is not a RTOS.
Moreover, you should not care whether sleep() returns in 1003 or 1004 milliseconds. You seem to be combining two things:
Determining how much time has elapsed since you synchronized the time
Displaying the current synchronized time
These have nothing to do with each other.
Use your sleep() loop -- or, better yet, postDelayed() for greater efficiency -- only to get control roughly every second to know that you need to update the TextView.
To determine what value to show in the TextView, do not add some assumed amount of time based on the sleep(). Instead:
When you get the synchronized time value from the other device, also save the current value of SystemClock.elapsedRealtime()
To determine how much time in milliseconds has elapsed since the synchronization, subtract the saved value of elapsedRealtime() from the current value of calling elapsedRealtime()

Problems with accelerometer's reading taking interval

How can i set the reading taking interval for accelerometer? I have tried to insert a value in the registerlistener but it still running at the same interval. I inserted 5000 * 1000 but it still running at the same interval. What can i do to set an interval for it?
You can't directly set the interval for accelerometer reading, as the system controls this. The only thing you can do is to use these flags when registering your listener:
SensorManager.SENSOR_DELAY_FASTEST
SensorManager.SENSOR_DELAY_GAME
SensorManager.SENSOR_DELAY_NORMAL
SensorManager.SENSOR_DELAY_UI
See here.
If you want to update the values on the screen at some frequency though, you can do it with runnable for example. You could also measure time in onSensorChanged() and update your variables only if specific amount of time has passed.

What is difference b/w invalidate() and postInvalidate()?

I am using PostInvalidate(40, Rect); means After 40 miliseconds it should again call the OnDraw() but it seems it is taking more than 40 miliseconds in calling onDraw().
Shall I invalidate() this on timer or handler. It is necessary for me to call it within 40 miliseconds
Any suggestions
From the documentation:
Cause an invalidate of the specified area to happen on a subsequent
cycle through the event loop. Waits for the specified amount of time.
Which means that the system will wait 40 milliseconds, then in a subsequent cycle through the event loop, it will do the invalidation. If you have a slow event cycle, you will get a slow response to the invalidation.
That means that the time required for the invalidation to take effect is limited by how long it takes to cycle through your event loop. It will never happen in 40 milliseconds. Whatever average time it takes for an Invalidate() to work, it will take that amount of time + 40 milliseconds more (at least).

Android Chronometer start with defined value

I have an application in which I'm displaying a chronometer to the user for what he's doing.
Whenever the activity goes to the background (wether by home button, or back) I save that time (in seconds) and when the activity is brought back, I want to continue the chronometer running from the same time. The user might select a different item from the list, and the time is different, and also he might turn off the phone...
I can save the time of the chronometer, however I can't set it with a start time.
From the Chornometer API, the method setBase() states:
Set the time that the count-up timer is in reference to.
On my understanding, this means that if I set this value to currentTime, it'll start counting with 0.
Now, if I want it to start with the value 17s I thought about setting the base to the currentTime less the time 17 seconds ago. So something like:
setBase(system.currentTimeMillis() - (17 * 1000)).
However this doesn't work, and the it starts always with 0!
I read a few other threads around here, and none of the answers helped. It always starts with 0!
Thanks in advance.
I think you're going to have to keep track of some time marks yourself.
Chronometer myChrono;
long baseTime;
long stopTime;
long elapsedTime;
When you set the base time, you want to use:
baseTime = SystemClock.elapsedRealtime() - stopTime;
myChrono.setBase(baseTime);
When you want to see how much time has passed, use:
elapsedTime = SystemClock.elapsedRealtime() - myChrono.getBase();
Take a look at the SystemClock doc.
setBase(system.currentTimeMillis() - (17 * 1000))
Should be changed to
setBase(SystemClock.elapsedRealtime() - (17 * 1000))
In general:
mChronometer.setBase(SystemClock.elapsedRealtime() - (nr_of_min * 60000 + nr_of_sec * 1000)))
Hopefully this will save lots of u folks some time :)

Categories

Resources