7

I'm developing an app in which I should get the number of steps I made during a physical activity. I found this code:

- (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;
}

With this code when the display of the iPhone is on it works great, but when I switch off the display it doesn't work anymore. To tracking the position I saw that in iOS 7 there's a function "background mode". With this function I can get the coordinates when the iPhone display is turned off. Now I've to get the accelerometer values when the display is turned off, how I can do that? I read on the web that iOS doesn't permit to use accelerometer in background mode (only iPhone 5s with the coprocessor M7 can get the accelerometer value when the display is turned off), how I can count the steps by using accelerometer in background mode? I guess there should be a way otherwise I can't understand how Moves app works.

lucgian841
  • 1,830
  • 5
  • 34
  • 57
  • I tried your code in above question, but it is not counting accurate step even in foreground.Do you have any better idea or algorithm that can count user steps more accurately? – Bharat Apr 27 '15 at 08:36

1 Answers1

5

You cannot access the accelerometer when the display is turned off but you can monitor for location changes even when the display is off regardless of the iPhone model. According to my guess Moves app uses geolocation based changes to count steps. In the CLLocationManger docs, I read this

In iOS 6 and later, you can defer the delivery of location data when your app is in the background. It is recommended that you use this feature in situations where your app could process the data later without any problems. For example, an app that tracks the user’s location on a hiking trail could defer updates until the user hikes a certain distance and then process the points all at once. Deferring updates helps save power by allowing your app to remain asleep for longer periods of time.

- (void)allowDeferredLocationUpdatesUntilTraveled:(CLLocationDistance)distance timeout:(NSTimeInterval)timeout

If your app is in the background and the system is able to optimize its power usage, the location manager tells the GPS hardware to store new locations internally until the specified distance or timeout conditions are met. When one or both criteria are met, the location manager ends deferred locations by calling the locationManager:didFinishDeferredUpdatesWithError: method of its delegate and delivers the cached locations to the locationManager:didUpdateLocations: method. If your app is in the foreground, the location manager does not defer the deliver of events but does monitor for the specified criteria. If your app moves to the background before the criteria are met, the location manager may begin deferring the delivery of events.

So when you get a set of cached locations you could calculate the approximate number of steps that happened. I am just giving all my wild thoughts, its up to you!

See this also, seems interesting https://www.cocoacontrols.com/controls/somotiondetector

Satheesh
  • 10,998
  • 6
  • 50
  • 93
  • Thank you for the answer :)! More or less I understand what are you saying. I guess I should do this: get the coordinates with `LocationManager` from start to end, then I should calculate the distance from the begin to the end point and with this distance I've to approximate the number of steps with this equation:`steps = distance / medium length of an human step`. – lucgian841 Feb 28 '14 at 12:21
  • Let me know when your app's live on the store, I would like to give it a try!! – Satheesh Feb 28 '14 at 12:28
  • For now I tried it so: I get the coordinates, I calculate the distance in this way: `distance = [startLocation distanceFromLocation:currentLocation];` and I try to get the number of steps by using this formula: `int numSteps = distance / 0.8;`. I will try the app in a few minutes (when I go home) so next week I can tell you if this solution works or not – lucgian841 Feb 28 '14 at 16:30
  • I saw this, https://www.cocoacontrols.com/controls/somotiondetector may be it is of some help to you. – Satheesh Mar 17 '14 at 13:44