Как отслеживать местоположение пользователя в фоновом режиме?

Я ищу приложение или библиотеку с открытым исходным кодом для отслеживания местоположения пользователя в фоновом режиме. Сейчас пытаюсь сделать это с CLLocation и фоновыми задачами, но точности для моего случая не хватает. Не могли бы вы объяснить, как приложения, такие как «moves», «runkeeper», «endmondo», создают мой маршрут? Должен ли я использовать акселерометр и/или компас для создания маршрута между фоновыми точками CLLocation?

Некоторый код:

//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 протестировал мое приложение со следующими свойствами

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

В этом случае у меня около 10 сработавших событий за 1,5 часа поездки.


person Alexey Sidorov    schedule 04.07.2013    source источник
comment
Выложи хотя бы код где настраиваешь CLLocationManager и где запускаешь менеджер локаций.   -  person AlexWien    schedule 04.07.2013
comment
Вы установили запись фонового режима GPS в файле plist?   -  person AlexWien    schedule 04.07.2013
comment
@AlexWien конечно, я сделал.   -  person Alexey Sidorov    schedule 04.07.2013
comment
Протестировал со своим приложением: работает в фоновом режиме ios6, target = ios5   -  person AlexWien    schedule 04.07.2013
comment
@AlexWien только что обновил тему с тестом   -  person Alexey Sidorov    schedule 05.07.2013
comment
До сих пор не работает? Пожалуйста, но NSLog(didUpdateLocation) в качестве первой строки   -  person AlexWien    schedule 10.07.2013


Ответы (8)


Использовать

kCLLocationAccuracyBestForNavigation

проверьте это.

person Phillip Kamikaze    schedule 13.07.2013

Вам нужно добавить в свой файл «Info.plist» ключ UIBackgroundModes (массив) со значением «местоположение» (приложение регистрируется для обновления местоположения). Вы можете проверить все фоновые режимы здесь.

person Maxime Berail    schedule 15.07.2013
comment
Я уже сделал это. В фоновом режиме у меня около 10 срабатывающих событий locationUpdate за 1,5 часа поездки - person Alexey Sidorov; 16.07.2013

Итак, ваше приложение использует службы определения местоположения. Затем прочтите Руководство по программированию определения местоположения.

Вам нужно внести некоторые изменения в ваш Info.plist:

  • Если ваше приложение использует службы определения местоположения для правильной работы, добавьте службы определения местоположения в UIRequiredDeviceCapabilities.
  • если вашему приложению требуется оборудование GPS, добавьте GPS в UIRequiredDeviceCapabilities.
  • Если вам нужно, чтобы ваше приложение работало в фоновом режиме более 10 минут, добавьте местоположение в UIBackgroundModes. Затем ваш менеджер местоположений доставит местоположения после 10-минутного лимита.
  • вы также должны установить NSLocationUsageDescription (также можно локализовать)

Получение событий местоположения в фоновом режиме

Если вашему приложению требуется доставка обновлений местоположения независимо от того, находится ли приложение на переднем плане или в фоновом режиме, для этого есть несколько вариантов. Предпочтительным вариантом является использование службы значительного изменения местоположения, чтобы разбудить ваше приложение в подходящее время для обработки новых событий. Однако, если вашему приложению необходимо использовать стандартную службу определения местоположения, вы можете объявить, что ваше приложение нуждается в фоновых службах определения местоположения.

Приложение должно запрашивать фоновые службы определения местоположения только в том случае, если отсутствие этих служб может ухудшить его работу. Кроме того, любое приложение, которое запрашивает службы определения местоположения в фоновом режиме, должно использовать эти службы для предоставления пользователю ощутимой выгоды. Например, приложение для навигации с пошаговой навигацией было бы вероятным кандидатом для фоновых служб определения местоположения из-за необходимости отслеживать положение пользователя и сообщать, когда пришло время сделать следующий поворот.

person Ravi_Parmar    schedule 17.07.2013

Ваша проблема - фоновый обработчик. Удалите его и включите фоновый режим gps в файле plist. тогда вы должны получать полную мощность gps все время.

Установить свойство pausesLocationUpdatesAutomatically=NO

Это новое в ios6.

Из CLLocationManager:

Разрешение диспетчеру местоположения приостанавливать обновления может увеличить срок службы батареи на целевом устройстве без ущерба для данных о местоположении. Если для этого свойства задано значение YES, менеджер местоположений приостанавливает обновления (и выключает соответствующее оборудование) в моменты, когда маловероятно, что данные о местоположении изменятся. Например, если пользователь останавливается, чтобы поесть во время использования навигационного приложения, диспетчер местоположений может приостановить обновления на определенный период времени. Вы можете помочь в определении того, когда следует приостановить обновления местоположения, присвоив значение свойству activityType.

Значение по умолчанию для этого свойства — YES.

Для анализа добавьте эти методы к вашему делегату LocationManager:

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

- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager {
    NSLog(@"locMan: locationManagerDidResumeLocationUpdates");
}
person AlexWien    schedule 04.07.2013
comment
Justed протестировал мое приложение со следующими свойствами self.locationManager.distanceFilter = kCLDistanceFilterNone; self.locationManager.desiredAccuracy = kCLLocationAccuracyBest; self.locationManager.activityType = CLActivityTypeFitness; self.locationManager.pausesLocationUpdatesAutomatically=NO; В этом случае у меня есть около 10 срабатываний событий во время 1,5-часовой поездки. - person Alexey Sidorov; 05.07.2013
comment
я проверил вчера свою работу. попробуйте точностьBestForNavigation. если шляпа все еще не работает, попробуйте скомпилировать для целевой iOS 5 - person AlexWien; 06.07.2013

Вы можете настроить мониторинг местоположения в своем VC, как показано ниже.

в методе viewDidLoad сделайте, как показано ниже

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

чем вам нужно переопределить ниже два необязательных метода делегата протокола CLLocationManagerDelegate

для iOS6+

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

и для iOS 2 до 6

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

в этих методах вы получите обновленное местоположение. используйте его, как хотите. каждый раз, когда местоположение обновляется, этот метод получает вызовы.

person Suryakant Sharma    schedule 04.07.2013
comment
спасибо за ваш ответ, но Im looking for a solution to track location in the background mode, like "moves", "runkeeper" does. I have tried to use CLLocation` с kCLLocationAccuracyBest в фоновом режиме, но событие срабатывает только каждые 500 метров, этого мне недостаточно. - person Alexey Sidorov; 04.07.2013
comment
@AlexeySidorov исправление срабатывает почти каждую секунду или каждую секунду, в зависимости от вашей скорости. прочитайте его ответ еще раз, ваше приложение работает в ios5? - person AlexWien; 04.07.2013
comment
@AlexWien это работает в ios6. Событие в фоновом режиме срабатывает не чаще чем на 500 метров, зависит от вышек сотовой связи. Я только что проверил это. - person Alexey Sidorov; 04.07.2013
comment
Взгляните на github.com/sidorov-panda/Record-my-position Работает так же, а количество срабатывающих событий маловато для меня - person Alexey Sidorov; 04.07.2013
comment
@AlexeySidorov Я портировал свое приложение с ios5 на ios6 на прошлых выходных, посмотрю, как оно себя ведет в фоновом режиме. - person AlexWien; 04.07.2013

вы не просите код. Вы спрашиваете: «Я ищу приложение или библиотеку с открытым исходным кодом».

Вам может помочь посещение этого веб-сайта.

надеюсь, это поможет вам,

Также есть руководство.

person Marc Millet    schedule 17.07.2013
comment
Я ищу приложение или объяснение метода, как такие приложения, как движения, делают то же самое - person Alexey Sidorov; 17.07.2013
comment
Это очень хорошее приложение, я тоже им пользуюсь. Вы можете сделать это кодирование в html5 и использовать фреймворк Cordova, чтобы закончить свое приложение и добавить его в магазины Android и Apple. - person Marc Millet; 17.07.2013
comment
Мне нужно отслеживать ходьбу в фоновом режиме, мне недостаточно точности этого приложения - person Alexey Sidorov; 17.07.2013
comment
Приложение RunKeeper похоже на приложение Moves, исходный код которого можно найти на github github.com/brierwood/RunKeeper-iOS. - person Marc Millet; 17.07.2013
comment
Спасибо за вашу ссылку, это было полезно, но RunKeeper автоматически создаст для вас правильный путь с отметкой времени, если вы публикуете уведомления. RunKeeperPathPoint *point = [[[RunKeeperPathPoint alloc] initWithLocation:newLocation ofType:kRKGPSPoint] autorelease]; [[NSNotificationCenter defaultCenter] postNotificationName:kRunKeeperNewPointNotification object:point]; - person Alexey Sidorov; 17.07.2013
comment
Алексей я не ios pro coder и с кодом помочь не могу, мои навыки html5 и css3, мои знания ios на среднем уровне. - person Marc Millet; 17.07.2013

Вот мое решение этого,

Объявите переменную экземпляра:

CLLocationManager *locationManager;

Обязательно включите делегата

<CLLocationManagerDelegate>

В представленииDidLoad:

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];

Реализуйте метод делегата:

- (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;
}
person jsetting32    schedule 17.07.2013
comment
Метод didUpdateToLocation устарел и заменен на didUpdateLocations: в iOS6. - person Kheldar; 01.12.2014

Отказ от ответственности: я работаю в Cintric

Мы также хотели иметь возможность точно отслеживать местоположение пользователей в фоновом режиме (даже после того, как приложение было убито). Мы потратили много времени на решение проблемы, особенно сосредоточившись на разрядке батареи.

Мы опубликовали отличный запись в блоге о том, как мы решили эту проблему. А также предоставляет SDK-решение для перетаскивания. Это не открытый исходный код, но вы можете интегрировать его бесплатно:

Вы можете скачать файл .framework, перетащить его в свой проект и инициализировать одной строкой кода: [CintricFind initWithApiKey:@"YOUR_API_KEY_HERE" andSecret:@"YOUR_SECRET_HERE"];

Вы можете получить ключ API бесплатно. Документы объясняют все здесь.

person Joel Green    schedule 27.10.2014
comment
http://www.blog.cintric.com/?p=121 не ссылается на статью. Вы можете исправить ссылку? - person Matt; 21.07.2015
comment
Ссылка должна быть исправлена ​​:) - person Joel Green; 28.07.2015
comment
Эта библиотека не подходит. Используйте старую карту, и местоположение будет обновлено неправильно. - person Brave; 19.04.2016