I'm currently working on an app that I want for my app to detect a beacon in background mode just when it gets close to it(Immediate). Based on articles that I've read it cannot be done with didEnterRegion and I should use ranging while it's running in the background mode(Location Update). is there any solution that directly reduces the didEnterRegion threshold? or Should I use the other method? and if that's the case does it work like didEnterRegion but with a limited range of RSSI? does it work when my phone entered the region and it's locked and the screen is off?
Monitoring APIs give you no control over the distance at which you get detection callbacks. You always get a callback the first time a beacon goes within radio range, typically at around 40 meters.
There are two ways to trigger on beacons only at close range:
Configure a lower radio transmission power on your beacon, if the manufacturer supports it.
Combine Ranging APIs with Monitoring, and range for as long as possible in the background (180 secs max on iOS without special background permissions), then trigger your logic when a ranging callback says the CLBeacon accuracy field is immediate.
Option 1 is simpler, but less reliable as it will often trigger at greater distances than you'd like and sometimes has trouble triggering at all even at extremely close range.
Option 2 is more reliable, so long as background ranging time does not run out. If a phone's radio triggers at 40 meters to start ranging, if the user takes more than 180 secs to get to immediate proximity then ranging time runs out and you are unable to get a trigger until the beacon disappears and reappears to reset the ranging time allowed.
Related
I want my Android application to be notified when the user is moving fast.
(lets say faster then 5 meter/second)
It must be battery efficient - so I can not use GPS for example, but can use a sensor.
Latency is not very important - it can be up to 30 seconds after reaching a fast speed.
I am only interested in continues movement. fast tilting the device can be ignored.
How can this be done ?
We are developing an app that has heavy GPS usage, and we are unable to optimize the battery life.
Even when the device is not moved, there is significant battery drainage that, according to the code, should not happen.
Here is the code:
locationManager = [[CLLocationManager alloc] init];
locationManager.distanceFilter = 100;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[locationManager startUpdatingLocation];
Ideally we want to trigger GPS every 20 minutes (if there is no location change then save battery) OR every 5 minutes if there is location change. According to my developer this cannot be done
Previously we were using kCLLocationAccuracyBest, which was consuming battery very fast and now we are using kCLLocationAccuracyHundredMeters.
startUpdatingLocation - is to get the GPS coordinates. There is another call startMonitoringSignificantLocationChanges which is to get AGPS coordinates which I believe returns the coordinates whenever cell tower will change, and hence consumes battery really fast.
distanceFilter - The minimum distance (measured in meters) a device must move laterally before an update event is generated. On the basis of distance filter we get the GPS fix from the device and then we send the updated GPS coordinates to the server.
Any help will be greatly appreciated
Thank you!
There is another call startMonitoringSignificantLocationChanges which
is to get AGPS coordinates which I believe returns the coordinates
whenever cell tower will change, and hence consumes battery really
fast.
That's exactly what it does, but you're jumping to conclusions about the power required for that. The GPS receiver and WiFi transceiver can be used to help determine location, but they're extra devices that have to be powered to be useful. But mobile phones like the iPhone need to keep in touch with the nearest cell tower anyway in order to receive phone calls, so using cell towers as a source of location information should be very efficient with respect to power. Here's what the CLLocationManager reference page says about -startMonitoringSignificantLocationChanges:
This interface delivers new events only when it detects changes to the
device’s associated cell towers, resulting in less frequent updates
and significantly lower power usage.
It also describes the service as providing "tremendous power savings," so it seems the right tool for the job you describe. Of course, if you're also using the standard location updating mechanism at the same time you won't see that power savings, so make sure you're not using both.
Ideally we want to trigger GPS every 20 minutes (if there is no
location change then save battery) OR every 5 minutes if there is
location change. According to my developer this cannot be done
It sounds like there's some sort of misunderstanding here. You can certainly fire up the GPS every 20 minutes to get a fix if that's what you want, although you can't do that from the background. The significant location change service will notify your app even if it's running in the background, so perhaps your developer is talking about background updates.
Your belief that startMonitoringSignificantLocationChanges consumes the battery really fast is likely incorrect. Cell tower changes usually occur far less frequently than movements of 100 meters. And an iPhone checks for this event even when idle and all apps are sleeping.
However, keeping a cell phone on (e.g. Airplane mode off) when far from any tower (barely 1 bar) will drain the battery of the device whether or not an app is doing any location monitoring.
On stock iOS devices, an app cannot trigger location monitoring purely on a timer basis such every 20 minutes or every 5 minutes, without keeping the device on and your app running in the foreground, which will drain the battery.
If you require a good level of precision, you should startUpdatingLocation and as soon you get the first fix you should then stopUpdatingLocation and then startMonitoringSignificantLocationChanges.
This is enough for most app purposes.
Ideally we want to trigger GPS every 20 minutes (if there is no
location change then save battery) OR every 5 minutes if there is
location change. According to my developer this cannot be done
This could be done using an NSTimer that calls a startLocating (a custom method that creates the CLLocationManager and calls startLocating on it) method every 20 minutes. Make sure you call CLLocationManager's stopLocating once you've found a CLLocation with an accuracy of your liking.
However, doing so mean that for 20 minutes you might be using a location that is totally off. It depends on how you plan to use the location and how precise it needs to be, but maybe what your dev means by "not possible" is that your app needs the user's actual location at all times.
I'm trying to create my own loadbar; It consists of 5 bars, sliding in from the bottom from the left to the right, then sliding out to the top in the same order. There should be a fixed amount of time (say, 0.2 seconds) between all of them sliding in.
Currently, i'm using a timer to start them one by one, and then let themselves repeat. However, if there's some lag during start or something, they get messed up. The first two or sometimes 3 bars go almost simultaneously, the gap is bigger, just name it and it happened. I currently just set fixed times when each animation should start, but some lag makes them go bogus.
Any given bar moves up in about 0.3 seconds, waits there for 0.2 seconds, then moves further up in 0.3 seconds. They start 0.2 second after their left neighbour, from left to right. Once they started, they just repeat it.
So, what could i use to coordinate them in such a way, that there will always be the same amount of time between them?
Other things i have considered was just using a lot of images (but that will need lots of images i suppose), or using Key Value Observing (KVO) to see when the previous bar is at the desired height.
According to the NSTimer documentation, NSTimer objects are not guaranteed to be realtime accurate on iOS.
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. If a timer’s firing time occurs during a long callout or while the run loop is in a mode that is not monitoring the timer, the timer does not fire until the next time the run loop checks the timer. Therefore, the actual time at which the timer fires potentially can be a significant period of time after the scheduled firing time.
It's an issue that effects NSTimer as well as OpenGL based games. Michael Daley mentions something similar in his book about how to set things up properly for an openGL based game. I suspect that this is suffering from the same similar situation.
That said, I would suggest preloading those images a adding them to the view just outside the bounds or frame of the visible view before you need then so that they are immediately available when you need them.
Addendum:
After thinking about this, I'm wondering if the C function wait() will help you here. It's a long shot, but perhaps it's worth a try. If not, then the answer may very well be that there is none.
Addendum 2:
I have no idea if this is going to help you either, but I found this page, which discusses pausing a program for less than a second.
I have developed a test for iPod/iPhone (with MonoTouch if that is relevant) that measures reaction time. But I need to take into consideration the time between touching the screen and actual triggering of the button event. Is there any documentation of that?
It's already very hard to almost impossible to get predictable interrupt latency on real time operating systems.
But on the iPhone? Imho impossible. A capacitive touchscreen is not optimal to get results that are exactly the same for each body and location. And if mail.app decides to poll for emails just at the moment you'll touch the screen there will be a bigger delay.
But to make one thing clear, we are speaking about some micro seconds or even less than that.
If you want accurate results you shouldn't use an iPhone. But I guess your app will be some kind of game, so nobody cares if your result is 0.01 seconds off. But I wouldn't show results as 0.381829191 seconds, that fakes accuracy you'll never get on any smartphone.
What is the lowest reaction time you got in your app?
The time between an actual touch and the system registering it will be negligable.
One key thing: if you are detecting the press using touch events like touchUpInside, consider using the touchesDownInside event because touchesUpInside, will not fire until the user's finger leaves the screen.
I am trying to made a musical iPhone application and I am having some problems playing looped samples.
I have read this question:
audio-on-the-iphone
and several other posts and blogs in the web about the "RemoteIO"/AudioUnits framework but without success.
I have been able to do a sample application that plays a finite sound with a predefined duration (I am using a playbackCallback) but I need the sound to start playing with the user touches the screen and stop playing when the user lift the finger.
Any ideas?
Thanks in advance.
Assuming your code is correct, you're probably omitting one (or more) of these steps:
Stopping reading/writing at the wrong times (because you're likely writing 'a power of 2' samples per render call)
Not providing a fade in/fade out (start at 10 ms fade out and adjust as desired)
Not stopping write on a zero crossing
not resetting the read position to 0 when the user lifts their finger - resuming in the middle of the sample
Your samples are not properly trimmed to zero crossings at start, end, and/or loop positions
Not resetting internal effects, filters, or convertors
You will not need all of these to avoid clicks.