How to track user location in background?
Asked Answered
H

7

20

I'm looking for an open source app or library to track user location in the background. Now I'm trying to do it with CLLocation and background tasks, but accuracy is not enough for my case. Could you explain, how apps, like "moves", "runkeeper", "endmondo", creates my route? Should I use Accelerometer or/and compass to create a route between CLLocation background points?

Some code:

//location manager init
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;


#pragma mark - CLLocationManager Delegate

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {

    if ([self isInBackground]) {
        if (self.locationUpdatedInBackground) {
            bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler: ^{
                [[UIApplication sharedApplication] endBackgroundTask:bgTask];
            }];

            self.locationUpdatedInBackground(newLocation);
            [self endBackgroundTask];
        }
    } else {
        if (self.locationUpdatedInForeground) {
            self.locationUpdatedInForeground(newLocation);
        }
    }
}

UPD: Justed tested my app with next properties

self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.activityType = CLActivityTypeFitness;
self.locationManager.pausesLocationUpdatesAutomatically=NO;

In this case I have about 10 fired events during 1,5 hour trip

Housewife answered 4/7, 2013 at 8:51 Comment(6)
Post at least the code where you set up the CLLocationManager and where you start the location manager.Dumfound
Have you set the GPS background mode entry in the plist file?Dumfound
@Dumfound sure, I did.Housewife
I tested it with my app: it works in background mode ios6, target = ios5Dumfound
@Dumfound just updated topic with some testHousewife
Still not working? Please but a NSLog("didUpdateLocation") as first lineDumfound
A
7

Use

kCLLocationAccuracyBestForNavigation

check this.

Adagietto answered 13/7, 2013 at 0:12 Comment(0)
M
6

You need to add in your "Info.plist" file the key UIBackgroundModes (array) with the value "location" (app registers for location updates). You can check all background modes here.

Mcgruder answered 15/7, 2013 at 22:32 Comment(1)
I already did it. In the background mode I have about 10 fired locationUpdated events during 1.5 hour tripHousewife
E
4

So your app uses location services. Then please read the Location Awareness Programming Guide.

You need to make some changes to your Info.plist:

  • If your app relies on location services to function properly, add location-services to UIRequiredDeviceCapabilities
  • if your app requires GPS hardware, add gps to UIRequiredDeviceCapabilities
  • if you need to run your app longer then 10 minutes in the background, add location to UIBackgroundModes. Then your location manager will deliver locations beyond the 10-minute-limit.
  • you should also set NSLocationUsageDescription (can also be localized)

Getting Location Events in the Background

If your app needs location updates delivered whether the app is in the foreground or background, there are multiple options for doing so. The preferred option is to use the significant location change service to wake your app at appropriate times to handle new events. However, if your app needs to use the standard location service, you can declare your app as needing background location services.

An app should request background location services only if the absence of those services would impair its ability to operate. In addition, any app that requests background location services should use those services to provide a tangible benefit to the user. For example, a turn-by-turn navigation app would be a likely candidate for background location services because of its need to track the user’s position and report when it is time to make the next turn.

Elene answered 17/7, 2013 at 11:2 Comment(0)
D
3

Your problem is the background handler. Remove it and enable gps background mode in plist file. then you should get full power gps all the time.

Set property pausesLocationUpdatesAutomatically=NO

This is new in ios6.

From CLLocationManager:

Allowing the location manager to pause updates can improve battery life on the target device without sacrificing location data. When this property is set to YES, the location manager pauses updates (and powers down the appropriate hardware) at times when the location data is unlikely to change. For example, if the user stops for food while using a navigation app, the location manager might pause updates for a period of time. You can help the determination of when to pause location updates by assigning a value to the activityType property.

The default value of this property is YES.

For analysis add these methods to your LocationManager delegate:

- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager {
     NSLog(@"locMan: locationManagerDidPauseLocationUpdates");
}

- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager {
    NSLog(@"locMan: locationManagerDidResumeLocationUpdates");
}
Dumfound answered 4/7, 2013 at 19:38 Comment(2)
Justed tested my app with next properties self.locationManager.distanceFilter = kCLDistanceFilterNone; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; self.locationManager.activityType = CLActivityTypeFitness; self.locationManager.pausesLocationUpdatesAutomatically=NO; In this case I have about 10 fired events during 1,5 hour trip.Housewife
i tested yesterday mine work. try accuracyBestForNavigation. if hat stil does not work try compliling to target ios 5Dumfound
C
2

You can set up monitoring location stuff in you VC as below

in viewDidLoad method do as below

CLLocationManager locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;(Accuracy according to your need)
[locationManager startUpdatingLocation];

than you have to overrite below two optional delegate methods of CLLocationManagerDelegate protocol

for iOS6+

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{}

and for iOS 2 to 6

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation

in these methods you will get updated location. use it as you want. every time location updated these method get calls.

Cestus answered 4/7, 2013 at 11:0 Comment(5)
thx for your response, but Im looking for a solution to track location in the background mode, like "moves", "runkeeper" does. I have tried to use CLLocation` with kCLLocationAccuracyBest in the background mode, but the event fires only evry 500 meters, that is not enough for me.Housewife
@AlexeySidorov the fix fires nearly evry second, or evry second depening on your speed. read his answer again, does your app work in ios5?Dumfound
@Dumfound it works in ios6. The event, in background mode, fires no often than 500 meters, depends on cellular towers. I just tested it.Housewife
Take a look at github.com/sidorov-panda/Record-my-position It works in the same way, and the number of fired events is too small for meHousewife
@AlexeySidorov I ported my app from ios5 to ios6 last weekend, i will look how it behaves in background mode.Dumfound
B
0

Here was my solution to this,

Declare the instance variable:

CLLocationManager *locationManager;

Be sure to include the delegate

<CLLocationManagerDelegate>

In viewDidLoad:

locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move, location is updated
locationManager.desiredAccuracy = kCLLocationAccuracyBest; // get best current locaton coords
locationManager.headingFilter = 1;
[locationManager startUpdatingLocation];
[locationManager startUpdatingHeading];

Implement the delegate method:

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    int degrees = newLocation.coordinate.latitude;
    double decimal = fabs(newLocation.coordinate.latitude - degrees);
    int minutes = decimal * 60;
    double seconds = decimal * 3600 - minutes * 60;
    NSString *lat = [NSString stringWithFormat:@"%d° %d' %1.4f\"",
                     degrees, minutes, seconds];
    NSLog(@" Current Latitude : %@",lat);
    latitudeLocation.text = lat;
    degrees = newLocation.coordinate.longitude;
    decimal = fabs(newLocation.coordinate.longitude - degrees);
    minutes = decimal * 60;
    seconds = decimal * 3600 - minutes * 60;
    NSString *longt = [NSString stringWithFormat:@"%d° %d' %1.4f\"",
                       degrees, minutes, seconds];
    NSLog(@" Current Longitude : %@",longt);
    longitudeLocation.text = longt;
}
Being answered 17/7, 2013 at 5:50 Comment(1)
The didUpdateToLocation method has been deprecated and replaced with didUpdateLocations: in iOS6.Schizomycete
P
-3

Disclaimer: I work for Cintric

We also wanted to be able to accurately track a users location in background (even after the app had been killed). We spent a long time solving the problem, especially focusing on battery drain.

We posted a great blog post on how we solved it. And also are providing a drag and drop SDK solution. It's not open source but you can integrate it for free:

You can download the .framework file, drag it into your project and initialize with one line of code: [CintricFind initWithApiKey:@"YOUR_API_KEY_HERE" andSecret:@"YOUR_SECRET_HERE"];

You can get an API key for free. There are docs explaining everything here.

Peptize answered 27/10, 2014 at 0:15 Comment(3)
http://www.blog.cintric.com/?p=121 doesn't link to the article. Can you fix the link?Estep
The link should be fixed :)Peptize
This library is not good. Use old map, and location is updated wrongly.Contusion

© 2022 - 2024 — McMap. All rights reserved.