My iOS application relies heavily on GPS and I tried writing a method that helps conserve battery but I am having little success.
I created an NSTimer that fired every 15 seconds. Every time the method was called, it would increment an int time up by 1. If int time reached 20(5 minutes) it would turn off the location updates and set a bool isStopped to true. Every time the method ran and int time was above 20, it would increment another int, int time2, up by 1. If the method was ran and int time2 was equal to 4, it would start the location updates again and set time2 to 0.
Then in the didUpdateLocation: method for the location manager, I have an algorithm that would first check if the bool isStopped was true, if it was true then it would check the new location's horizontal accuracy and make sure it was under 10. Then it would check the newLocation with a location object named coords and check to see if they were greater than 9 meters apart. If they were not, it would stop location updates again and return. If they were, it would continue to another algorithm where it would check the new location object against some arguments. If it passed the coords location object would be set with the new location object, the time and time2 ints would be set to 0, the isStopped would be set to false, and the whole process would start all over again.
In short, after 5 minutes of no location changes, the location updates would be stopped and periodically checked every 1 minute to see if the user had moved at least 10 meters from the previous location that passed all requirements. When the user does move far enough, it starts the process all over again and the user has to not move 10 or more meters for 5 minutes before it starts the periodic checks. The thought behind this is to do only few second checks every minute when the user isn't moving much instead of constantly having the location services running.
Now here's the problem I run into, when the location updates stop. The NSTimer stops running while the app is in the background.
Could I somehow schedule a background task to run the loop between the 1 minute checks? Does anyone have any better ideas? Or any ideas on solutions to this?
A while ago I asked a question that features all the different ways that you can run GPS in the background.
CLLocationManager geo-fencing/startMonitoringForRegion: vs. startMonitoringForSignificantLocationChanges: vs. 10-minute startUpdating calls
You have to do specific things in order to maintain GPS in the background. A NSTimer would not suffice, since you need to register your app to be allowed to keep it running in the background after ten minutes. You minimally have to run the GPS every 10 minutes in the background to keep your app running.
Anyway, the methods in the above post should answer your question.
Related
I have a program in SWIFT, that detects when a beacon or multiple beacons are out of range and based on
that it will perform something like saving some data into database and etc. Everything works well, however I do get lots of
false positive in a way that "didExitRegion" getting fired and few secs later "didEnterRegion" getting fired while I haven't been moved or etc.
I know this has lot to do with the tuning of the beacons and their qualities, but at this time I have come up with an alternative solution.
So I decided to use NSTimer to see if I am really off range or is it just a false positive that I am getting?
so when didExitRegion is getting fired, I start a NSTimer for 60 secs. If the 60 secs is up and didEnterRegion didn't get fire, then I know
I am really out of range and perform whatever data saving I need to do.
Otherwise if didEnterRegion is called within that 60 secs, then I'll assume it was a false positive and invalidate the
nstimer and not doing anything.
Everything works well as long as I am working with one beacon. The problem I have with timer is when multiple beacons go out of range.
lets say first beacon is out of range, so didExitRegion is getting fire and start the NSTimer
Let say 20 secs later second beacon is off range and again didExitRegion is getting fired and that one starts the NSTimer again.
Now my NStimer is all out of synch and at that time, things are not working correct and the NSTimer continuously start itself when 60 secs
is up and etc.
So my question is what is the work around this solution? How can I keep my nstimer in synch when is called again before is invalidated?
Is there a better way to this solution? Again, I know a better quality beacons can help, but that is not an option for me at this time.
One solution is to keep a dictionary like this:
var pendingExits = Dictionary<CLBeaconRegion,NSDate>()
Each time you get a didExitRegion call:
Only start the NSTimer if the dictionary is empty -- otherwise, assume the timer is already running.
Add the region to the dictionary along with a new NSDate() to set the timestamp of when it was added.
When you get a didEnterRegion callback:
Look for the region in the dictionary. If it is there, remove it.
When the timer goes off:
Look for any entry with a timestamp 60 seconds or more old. For this, remove the region from the dictionary and fire your custom exit logic.
Find the newest remaining timestamp (if any) in the dictionary. Start the timer to go off at that time plus 60 seconds.
I have a NSTimer (running on main thread) that is supposed to go off every 0.02s. However, I notice that as memory usage start going up (the app captures a frame every tick and stores in an array) subsequent ticks begin to take more then 0.02s.
How can I solve this issue? I'm starting to think NSTimer is not suited for high-frequency tasks like this.
As the docs state,
A timer is not a real-time mechanism; it fires only when one of the
run loop modes to which the timer has been added is running and able
to check if the timer’s firing time has passed. Because of the various
input sources a typical run loop manages, the effective resolution of
the time interval for a timer is limited to on the order of 50-100
milliseconds.
Since 100 milliseconds = .1 seconds and your timer is supposed to run every 0.02 seconds, your timer schedule is far shorter than the timer's effective resolution and so you timer can easily get out of sync.
I want to ask how is GeofenceState.Exited intended?
When I have a background task with GeofenceState.Entered, when I move inside the circle, I get IBackgroundTask.Run() run every 2 minutes (why 2 minutes?)
But with GeofenceState.Exited, I can walk miles, but it never gets triggered. Is there some bug, or is that intended differently than I suppose? I guess it should work this way: when the check is done after 2 minutes, when I'm outside of the circle, the method Run is called.
I have a parameter 50 and dwell time 1 sec.
Thanks
I'm trying to create a label that shows the time on a NSTimer, however my problem is that the interval on the timer isn't 1.0 and so there is no way to update the label every second like I would like to be able to. I have tried to synchronize two timers, however that is proving to be a challenge. So, Is there a way to get secondary updates or synchronize two timers of different interval?
I'm reading your question as follows:
I have a timer that needs to fire once per 5 seconds, but I would like to tell the user how many seconds remain until the timer fires.
The simplest way that I can think of is to make an intermediary method that the first timer will call. You would change:
timer -> METHOD_A
to
timer -> METHOD_B -> METHOD_A
the timer could then be set to update every .1 seconds, and METHOD_B could keep track of the time and just call METHOD_A when 5 seconds have passed since the previous call.
For what it's worth though I don't think that NSTimer will slip, so when you are updating the time you are probably doing something like time=time+interval, where it might make more sense to do (currentTime-startingTime)%interval, and then the synchronization shouldn't be a problem
I'm trying to execute a function(or procedure) every x seconds.
I've been looking everywhere but never seemed to find something that suits my needs.
My application basically gets data from the web and I want to make an auto-refresh checkbox.
So let's say the user checks the box, I want the app to call that function every 5 seconds.
Thanks!
Use a TTimer (from the System tab in the component palette). Set the interval to the number of seconds * 1000 (converting from milliseconds to seconds), and write a handler for the OnTimer event.
The simplest way it to use the TTimer component, part of Delphi's standard VCL. Put one on the form, make sure Enabled is set to True, set Interval to 5000 (the value is in milliseconds), and assign its OnTimer event, where you'll put the code that needs to run every 5 seconds.
Sometimes it is a good idea to start with the timer disabled, then set its Enabled property to true in code, so that the timer starts to fire after everything else in your application has been properly set up.
The timer may not be firing in exact 5-second intervals, since timer messages have low priority in Windows and may not be received if the CPU is doing a lot of other work. Since your interval is relatively long, you might set the timer to fire every second (Interval := 1000) or even a few times per second, and check current time every time it fires. Perform the update if current time is later by 5 seconds or more from the time of the last update. (Use the SecondsBetween function in DateUtils unit to make that determination).
I don't have Delphi at the moment, but I'm pretty sure there was a TTimer component in the control palette, and according to this, I think I'm right.