I'm trying to return time in milliseconds between both iOS and Android devices. I was hoping that since most devices sync their time with a networked server, they would be the same. However, I'm noticing they are not precisely the same.
I'm using this method for iOS:
[[NSDate date] timeIntervalSince1970]
and this for Android:
System.currentTimeMillis()
Is there a better way to try to return the same exact time across devices? I'm noticing these values can be off from each other by up to 2 seconds depending upon the Android device.
The use-case for needing this synchronized time is to display a looping animation that is also synced across the devices. So the animation would need to start at the same time, perform its animation for a set duration, and then loop again.
Thanks for any help.
You'll never get exactly the same time. The problem is that clocks aren't perfect, and that they aren't always synched to exactly the same time source at the same rate. Even if you synch to the same time source, the latency between when they process update messages will make a difference between them. 2 seconds is actually pretty good.
Time is tricky. Take 2 devices in perfect synchronimity. Fly from the US to Europe with one of them. They're no no longer in synch, and both are right- the general relativistic effects of traveling at high speed means one is now several milliseconds older than the other.
Basically what you want isn't going to happen. You'll have to settle for close enough. Although if you post why you need them so synchronized maybe we can give you some ideas.
Related
Recently I'm working on a mobile offline game based on Cocos2dx-lua.
I found an app on Google Play called GameGuardian which can set the time speed. The app maybe modify the method gettimeofday() in libc.so. I've tried many APIs such as os.time(), SystemClock.elapsedRealtime(), but all failed.
Could somebody please give me a way to avoid the effect of the app?
The only sure method is to make your app contact your game's server to ensure time. Many android games is doing that. "The Battle Cats" is one example.Say, you can check time validity as soon as app starts, and if no connection available, you can allow resources generated for some allowed time. Not more than 1 hour worth since last confirmed time, for example.
Other idea might be checking current fps. Hardware can't speed up, so frame will be rendered in roughly same time when VSync enabled. If you find that rendering single frame takes significantly more time than it should be, and if it happens for many frames, then it might indicate cheating possibility. But this is not stable solution, since you'll have to be sure your fps normally doesn't drop on weak devices, and it doesn't tell you anything about time spent while game wasn't running.
Extreme case might include complete erasing app's state if you find time jumped back since last saved unconfirmed time for more than ~1 hour (in case user adjust DST, etc).
But generally you can't protect completely offline game from time manipulations.
I'm looking to create a drum machine in ActionScript 3 (as an Adobe AIR Android app), which will keep to a user defined tempo (BPM).
I am struggling to find a way to keep the project in time, I have, at the moment, made it so that 5 different sounds are represented in rows of 8 squares, and the user can click each square to choose when to play that sound (hope this makes sense).
At the moment I am using Timer to keep the project in time, which is very laggy and inconsistent.
using timer is a bad idea for this, there I said it...
The issue is that the timer has a drift and fires several milliseconds later.
Try a simple test where you have a timer that executes every 500ms, and then compare the getTimer() count. What I have found in my experiments that the timer is continually off and it looks like it doesn't self correct. I've tried using a self-correcting timer, that changes the firing time based on the getTimer() difference since last run, but it's still not reliable. and anytime your processor's load picks up, the timer will be off anyway.
The correct way of dealing with this is to use byteArray data as a source for the sound. Based on the calculation of sampling resolution you can populate the stream with the data in advance, and the sound will play on time, pretty much guaranteed. I haven't gone as far as to create something that does this myself. But there are several libraries that you can utilize that can help you with this.
My top two decremented libraries are SiON and tonfall
you can see a sample of SiON here http://wonderfl.net/c/qf4b
and tonfall example at http://tonematrix.audiotool.com/
While I haven't tried them on android, I think either should work
Well i have successfully obtained the light value, however, it is EXTREMELY delayed. Approx 3~5 seconds even when using .SENSOR_DELAYED_FASTEST also even when entering 0 as the rate. Its so slow. I have the program check light sensor values upon screen on then change brightness accordingly HOPING it would solve the horrible automatic brightness delay. but after messing around with it, it seems to me that this is simply a flaw in android. It simply cannot update fast enough. I have used getDefaultSensor() but according to android documention this value can be delayed/filtered, but upon reading another post on stackoverflow the getSensorList() and getDefaultSensor() return the same values and that getSensorList() is no different than getDefaultSensor()
The reason for my question is: Is this correct? Is android simply a fail at updating immediatly? its funny cause my Windows MOBILE(not phone) can update immediatly and i loved it. but with all android devices ive seen its the same thing. so is this just a flaw in androids programming? Is there a way for me as an app dev to fix this? or do we have to live with it?
As I know you cannot get it faster. Please take a look on this question and answer: https://stackoverflow.com/a/5060690/1381641
I don't have the solution for your problem, but I do have an explanation for it. The Ambient light sensor has a delay because of the integration time downloads Sensor Box for android from the Playstore.
You will get the hardware ID of your ambient light sensor, then google search it, and you will get a PDF with technical details about that specific model number. Every Android or IOS phone does NOT use the same hardware.
In that PDF, you will get an integration time. It exists to keep the brightness control stable and delayed as well as sensible. If it is low, and you are in a disco your brightness level will keep on flickering. The same for outside, sometimes some shadows make it go up and down if the integration time is low. It will flicker more and will not be stable.
This will also cause harm to the backlight, so instead of taking single values they compile down the values of a big time interval. My integration time was 400ms. This value is sent to the processor, and then the decision is taken.
You could change this value. It is easy, AMD hard boh depends on your expertise like to update this you have to program the ALS unit by opening the phone, connecting a programmer to it, and connecting the pins in the right way. Then sending an 8 bit signal as mentioned in the PDF (if model is programmable).
I'm developing an engine and a game at the same time in C++ and I'm using box2D for the physics back end. I'm testing on different android devices and on 2 out of 3 devices, the game runs fine and so do the physics. However, on my galaxy tab 10.1 I'm sporadically getting a sort of "stutter". Here is a youtube video demonstrating:
http://www.youtube.com/watch?v=DSbd8vX9FC0
The first device the game is running on is an Xperia Play... the second device is a Galaxy Tab 10.1. Needless to say the Galaxy tab has much better hardware than the Xperia Play, yet Box2D is lagging at random intervals for random lengths of time. The code for both machines is exactly the same. Also, the rest of the engine/game is not actually lagging. The entire time, it's running at solid 60 fps. So this "stuttering" seems to be some kind of delay or glitch in actually reading values from box2D.
The sprites you see moving check to see if they have an attached physical body at render time and set their positional values based on the world position of the physical body. So it seems to be in this specific process that box2D is seemingly out of sync with the rest of the application. Quite odd. I realize it's a long shot but I figured I'd post it here anyway to see if anyone had ideas... since I'm totally stumped. Thanks for any input in advance!
Oh, P.S. I am using a fixed time step since that seems to be the most commonly suggested solution for things like this. I moved to a fixed time step while developing this on my desktop, I ran into a similar issue just more severe and the fixed step was the solution. Also like I said the game is running steady at 60 fps, which is controlled by a low latency timer so I doubt simple lag is the issue. Thanks again!
As I mentioned in the comments here, this came down to being a timer resolution issue. I was using a timer class which was supposed to access the highest resolution system timer, cross platform. Everything worked great, except when it came to Android, some versions worked and some versions it did not. The galaxy tab 10.1 was one such case.
I ended up re-writing my getSystemTime() method to use a new addition to C++11 called std::chrono::high_resolution_clock. This also worked great (everywhere but Android)... except it has yet to be implemented in any NDK for android. It is supposed to be implemented in version 5 of the crystax NDK R7, which at the time of this post is 80% complete.
I did some research into various methods of accessing the system time or something by which I could base a reliable timer on the NDK side, but what it comes down to is that these various methods are not supported on all platforms. I've went through the painful process of writing my own engine from scratch simply so that I could support every version of android, so betting on methods that are inconsistently implemented is nonsensical.
The only sensible solution for anyone facing this problem, in my opinion, is to simply abandon the idea of implementing such code on the NDK side. I'm going to do this on the Java end instead, since thus far in all my tests this has been sufficiently reliable across all devices that I've tested on. More on that here:
http://www.codeproject.com/Articles/189515/Androng-a-Pong-clone-for-Android#Gettinghigh-resolutiontimingfromAndroid7
Update
I have now implemented my proposed solution, to do timing on the java side and it has worked. I also discovered that handling any relatively large number, regardless of data type (a number such as the nano seconds from calling the monotonic clock) in the NDK side also results in serious lagging on some versions of android. As such I've optimized this as much as possible by passing around a pointer to the system time, to ensure we're not passing-by-copy.
One last thing too, my statement that calling the monotonic clock from the NDK side is unreliable is however, it would seem, false. From the Android docks on System.nanoTime(),
...and System.nanoTime(). This clock is guaranteed to be monotonic,
and is the recommended basis for the general purpose interval timing
of user interface events, performance measurements, and anything else
that does not need to measure elapsed time during device sleep.
So it would seem, if this can be trusted, that calling the clock is reliable, but as mentioned there are other issues that then arise, like handling allocating and dumping the massive number that results which alone nearly cut my framerate in half on the Galaxy Tab 10.1 with Android 3.2. Ultimate conclusion: supporting all android devices equally is either damn near or flat out impossible and using native code seems to make it worse.
I am very new to game development, and you seem a lot more experienced and it may be silly to ask, but are you using delta time to update your world? Altough you say you have a constant frame rate of 60 fps, maybe your frame counter calculates something wrong, and you should use delta time to skip some frames when the FPS is low, or your world seem to "stay behind". I am pretty sure that you are familiar with this, but I think a good example is here : DeltaTimeExample altough it is a C implementation. If you need I can paste some code from my Android Projects of how I use delta time, that I've developed following this book : Beginning Android Games.
I asked this question over in the Android Developer's user group, last week. Nobody responded, so I thought I'd ask it over here.
Does anyone have any suggestions about how to schedule video events to happen at an exact clock time? I've been thinking about an application that would require two adjacent phones to display the same thing at exactly the same time. I'm wondering what that granularity of "exactly" is going to be.
I've done some testing on a couple of devices and it seems that the delay between an invalidate and the subsequent redraw can be as much 16ms. Perhaps I can do better with OpenGL?
Ideas? Anyone?
OpenGL itself is capable of very high framerates (unless I am mistaken). What I can tell you is that plenty of games have been written to run and maintain 30 frames per second. That's one frame every 3.33ms. At that speed, the change should be imperceptible to the human eye, or so I've heard (the estimate limit is 5ms).
However, there is a major difference between what OpenGL can do, and what the device running OpenGL can do. Again, Unless I am mistaken, you should be able to instruct OpenGL to run at 200 frames per second. The caveat is that if the machine you are running the animation on can't handle that framerate, it will either frame-skip or lag, and in either case will hog the processor and GPU like no other.
Again, as I don't know the specifics, I can only guess, but I would think that this is less of an issue with OpenGL vs the other leading brand, and more of an issue of the devices you are trying to sync. With the right code, a proven framework, two powerful machines, and high-speed data transfer capability (read: LAN at the least), there is no reason why you shouldn't be able to sync up the video. If any of these things are not the case, all bets are off.
-Cody