Core Motion的加速度计在后台模式下实现的奇怪行为

Nim*_*sri 5 accelerometer background-process ios core-motion cmmotionmanager

我在iOS上实现了一个计步器.一个重要的要求是,即使应用程序处于后台模式(例如,设备被锁定或用户按下主页按钮),它也必须工作.您可以在App Store中看到这样的实现,如Nike +,Runtastic Pedometer等.

一些SO帖子证实,这可以通过Core Motion实现,或者特别是CMMotionManager具有Required background modes设置为的附加属性location.

我使用下面的代码进行了快速测试,发现了一个奇怪的问题:

// 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...
}
Run Code Online (Sandbox Code Playgroud)

我用iPhone 4S和iOS 6.1试过这段代码.当应用程序启动时,我按下主页按钮并摇动它(模拟行走)5秒钟,然后再次打开应用程序.这些动作重复了几次.我得到的输出是:

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
...
Run Code Online (Sandbox Code Playgroud)

我没有检查读数的正确性,但快速观察已经发现了一些问题.此应用程序第一次在后台模式下运行时,没有读数(有时只有一个读数).

我在这做错了什么?这是实施计步器的正确方法吗?