Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange behavior of Core Motion's accelerometer implemented in the background mode

I'm implementing a pedometer on iOS. An important requirement is it must work even if the app were to put in the background mode (e.g., a device is locked or a user presses the home button). You can see such implementation in the App Store like Nike+, Runtastic Pedometer and so on.

A few SO posts confirmed that this is made possible with Core Motion or, specifically, CMMotionManager with an additional property of Required background modes set to location.

I ran a quick test with the code below and found a strange problem:

// AppDelegate.m
- (void)applicationDidEnterBackground:(UIApplication *)application
{ 
    if(self.motionManager==nil) {
        self.motionManager=[[CMMotionManager alloc] init];
    }
    self.motionManager.accelerometerUpdateInterval=1/50;

    if(self.accelerometerReadings==nil) 
        self.accelerometerReadings=[[NSMutableArray alloc] init];

    [self.motionManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.accelerometerReadings addObject:accelerometerData];
        });
    }
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    NSLog(@"The number of readings %d",self.accelerometerReadings.count);

    // do something with accelerometer data...
}

I tried this code with an iPhone 4S and iOS 6.1. When the app is launched I press the home button and shake it (to simulate walking) for 5 seconds and open the app again. These actions get repeated a few times. The output I got is:

2013-02-05 16:41:42.028 [1147:907] readings 0
2013-02-05 16:41:51.572 [1147:907] readings 444
2013-02-05 16:42:00.386 [1147:907] readings 1032
2013-02-05 16:42:08.026 [1147:907] readings 1555
...

I didn't check the correctness of the readings, but quick observation already reveals some problem. There is no readings (or sometimes only one reading) at the first time this app ran in the background mode.

What am I doing wrong here? And is this a correct approach for implementing a pedometer?

like image 874
Nimit Pattanasri Avatar asked Nov 12 '22 12:11

Nimit Pattanasri


1 Answers

With M7 chip embedded in iPhone5s, an Apple built-in class, CMStepCounter, is probably the best way to go.

https://developer.apple.com/library/ios/documentation/CoreMotion/Reference/CMStepCounter_class/Reference/Reference.html#//apple_ref/doc/uid/TP40013504

like image 153
Nimit Pattanasri Avatar answered Nov 15 '22 07:11

Nimit Pattanasri