The new Nike+ GPS application for iOS 5 is able to process accelerometer events in the background (thus allowing for indoor treadmill tracking). How is this possible? When I put my application in background, it ceases receiving events. I use the standard UIAccelerometer API.
Asked
Active
Viewed 1.3k times
33
-
Please, anyone else can confirm it? Looks fantastic for Apple – AlexeyVMP Jan 12 '12 at 10:50
-
3I can confirm that it works! The only thing you need to meet - use any background mode to make you app running in the background (location updates, playback, VoIP or BT4 central). – AlexeyVMP Feb 15 '12 at 09:32
-
2Hey guys, thank's for your work so far! I tried your approach for a pedometer app. It almost works for me. I use the location background mode and update the user location every 9 minutes to prevent the app of becoming inactive - this mechanism works but the update queue doesn't contain any data after the first 9 minutes. Do you have any idea what goes wrong or maybe you could provide a little more detailed hint/solution to my problem? Thank's again! Hannes – Hannes Mar 04 '12 at 19:26
-
fyi, you can provide answer's for your own questions, please do use this. – thecoshman Mar 07 '12 at 09:42
-
2@kyrpoff how to get the accelerometer data after the first 10 min when the app is in background. – Madhu Jun 17 '13 at 09:24
2 Answers
14
For the sake of providing an answer to this question, even though it is already self answered...
"If you use the newer Core Motion API, you can receive updates in the background."
Here is an example:
- (void)startAccelerationCollection {
[self.motionManager startAccelerometerUpdatesToQueue:[[NSOperationQueue alloc] init]
withHandler:^(CMAccelerometerData *data, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.accelerometerReadings addObject:data];
});
}];
}

thecoshman
- 8,394
- 8
- 55
- 77
-
4This doesn't work after you press the home button. How can we fix that ? – Sumoanand Sep 05 '14 at 18:08
-
@Sumoanand - Yep. This does not work when the app gets suspended (when user presses the HOME button or switches app etc) – KamyFC Oct 18 '14 at 12:22
-
I see comments about this not working if the user presses the home button. Do those comments mean that this does work in all other cases? E.g. if the user leaves the phone idle until the screen dims, then the screen goes blank, does it work? What if the user presses the power button to turn the screen off? In both my examples I mean that the user has not pressed the home button since the App was opened, so it was the foreground App until the screen went blank. – Joe C Jun 23 '15 at 02:51
-
1The reason that this is not working for some people is that it is not the complete solution - if you just copy this into an otherwise empty project you'll not get any data when app is in the background. You need to enable some type of background mode (audio, location or something else that is meaningful for your app) and you need a background task to be running. See this reply: http://stackoverflow.com/a/23749230/997690 – N.J. Mar 29 '16 at 11:35
0
When the the block with update of pedometer, I call the method to turn Off and turn On the GPS. For me it fixed the problem when the user press home and stay for one hour listening music on spotify.
Don't forget to enable Project Settings -> Capabilities -> Background modes - > Location updates
import CoreLocation
import CoreMotion
//turn Off and turn On GPS
private func apelacaoRenovarGPSLigado() {
LocationManager.sharedInstance.stopUpdatingLocation()
let locationManager = LocationManager.sharedInstance
locationManager.autoUpdate = true
locationManager.startUpdatingLocationWithCompletionHandler { (location, status, verboseMessage, error) -> () in
}
}
private func startPedometer()
{
if CMPedometer.isDistanceAvailable()
{
if self.pedometer == nil
{
self.pedometer = CMPedometer()
}
self.pedometer!.startPedometerUpdatesFromDate(NSDate()) { (data, error) in
dispatch_async(dispatch_get_main_queue(), {
print("DISTANCIA PARCIAL \(data!.distance!)")
print("DIFERENCA \(data!.distance!.doubleValue - (self.totalDistance + self.subtotalDistance))")
self.delegate!.trackerDistanceDidChanged((data!.distance!.doubleValue - (self.totalDistance + self.subtotalDistance)) / 1000.0)
self.subtotalDistance = data!.distance!.doubleValue
self.apelacaoRenovarGPSLigado()
})
}
}
else
{
self.delegate!.trackerDeviceNotSupported()
}
}

Ronaldo Albertini
- 1,329
- 20
- 24