在iOS 7中后台获取步骤

7

我正在开发一个应用程序,需要获取我在体育活动中走的步数。我找到了以下代码:

- (void)countSteps {
    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0 / KUPDATEFREQUENCY];
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];

    px = py = pz = 0;
    numSteps = 0;

    self.labelSteps.text = [NSString stringWithFormat:@"%d", numSteps];
}

- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    float xx = acceleration.x;
    float yy = acceleration.y;
    float zz = acceleration.z;

    float dot = (px * xx) + (py * yy) + (pz * zz);
    float a = ABS(sqrt(px * px + py * py + pz * pz));
    float b = ABS(sqrt(xx * xx + yy * yy + zz * zz));

    dot /= (a * b);

    if (dot <= 0.82) {
        if (!isSleeping) {
            isSleeping = YES;
            [self performSelector:@selector(wakeUp) withObject:nil afterDelay:0.3];
            numSteps += 1;
            self.labelSteps.text = [NSString stringWithFormat:@"%d", numSteps];
        }
    }
    px = xx;
    py = yy;
    pz = zz;
}

- (void)wakeUp {
    isSleeping = NO;
}

使用这段代码时,当iPhone的显示屏开启时它能够正常工作,但是当我关闭显示屏时它就不再起作用了。为了跟踪位置,我发现在iOS 7中有一个名为“后台模式”的功能。使用这个功能,我可以在iPhone的显示屏关闭时获取坐标。现在,我需要在显示屏关闭时获取加速度计的值,我该怎么做呢?我在网上读到iOS不允许在后台模式下使用加速度计(只有带有协处理器M7的iPhone 5s可以在显示屏关闭时获取加速度计的值),那我该如何使用加速度计在后台模式下计算步数呢?我想应该有一种方法,否则我就无法理解Moves app是如何工作的。

我尝试了你在上面问题中提供的代码,但即使在前台也无法准确计算步数。你有更好的想法或算法可以更准确地计算用户步数吗? - Bharat
1个回答

5
当显示器关闭时,您无法访问加速度计,但是无论iPhone型号如何,即使显示器关闭,您仍然可以监视位置更改。根据我的猜测,Moves应用程序使用基于地理位置的更改来计算步数。在CLLocationManger文档中,我读到了这个:
在iOS 6及更高版本中,当您的应用程序在后台运行时,可以推迟位置数据的传递。建议您在应用程序可以稍后处理数据而不会出现任何问题的情况下使用此功能。例如,跟踪用户在徒步旅行中的位置的应用程序可以推迟更新,直到用户徒步行走一定距离,然后一次性处理所有点。推迟更新有助于节省电力,使您的应用程序保持睡眠状态更长的时间。
- (void)allowDeferredLocationUpdatesUntilTraveled:(CLLocationDistance)distance timeout:(NSTimeInterval)timeout

如果您的应用程序在后台运行,并且系统能够优化其电量使用,位置管理器会告诉 GPS 硬件将新位置存储在内部,直到满足指定的距离或超时条件。当满足一个或两个标准时,位置管理器通过调用其委托的 locationManager:didFinishDeferredUpdatesWithError: 方法结束延迟位置并将缓存的位置传递给 locationManager:didUpdateLocations: 方法。如果您的应用程序在前台运行,则位置管理器不推迟事件的传递,但会监视指定的标准。如果您的应用在达成标准之前移至后台,则位置管理器可能开始推迟事件的传递。
因此,当您获取一组缓存位置时,您可以计算大致发生的步数。我只是给出了我的所有想法,由您决定!
还可以参考以下链接,看起来很有趣: https://www.cocoacontrols.com/controls/somotiondetector

谢谢你的回答 :)!我更或多或少明白你在说什么。我想我应该这样做:使用LocationManager获取起点到终点的坐标,然后我应该计算从起点到终点的距离,并使用此距离来近似步数,使用此方程式:steps = distance / 人类步长的中等长度 - lucgian841
当你的应用程序在商店上线时,请告诉我,我想试一试! - Satheesh
目前我尝试了这样做:我获取坐标,然后用以下方式计算距离:distance = [startLocation distanceFromLocation:currentLocation]; 然后我尝试使用以下公式来获取步数:int numSteps = distance / 0.8;。我将在几分钟后(回家时)尝试该应用程序,所以下周我可以告诉您这个解决方案是否有效。 - lucgian841
我看到了这个网址,https://www.cocoacontrols.com/controls/somotiondetector 或许对你有所帮助。 - Satheesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接