Okresowe aktualizacje lokalizacji tła systemu iOS
Piszę aplikację, która wymaga aktualizacji lokalizacji w tle z wysoką dokładnością i niską częstotliwością . Rozwiązaniem wydaje się być zadanie tła NSTimer, które uruchamia aktualizacje menedżera lokalizacji, który następnie natychmiast się wyłącza. To pytanie zostało już zadane:
Jak uzyskać aktualizację lokalizacji w tle co n minut w mojej aplikacji na iOS?
Uzyskiwanie lokalizacji użytkownika co n minut po przejściu aplikacji do tło
IOS nie jest typowym problemem czasomierza śledzenia lokalizacji w tle
IOS long-running background timer with" location " background mode
IOS w pełnym wymiarze czasu pracy w tle-usługa oparta na śledzeniu lokalizacji
Ale nie mam jeszczeminimalnego przykładu działającego. Po wypróbowaniu każdej permutacji powyższych zaakceptowanych odpowiedzi, ułożyłem punkt wyjścia. Wpisywanie tła:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
NSLog(@"ending background task");
[[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}];
self.timer = [NSTimer scheduledTimerWithTimeInterval:60
target:self.locationManager
selector:@selector(startUpdatingLocation)
userInfo:nil
repeats:YES];
}
I delegat "metoda": {]}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"%@", newLocation);
NSLog(@"background time: %f", [UIApplication sharedApplication].backgroundTimeRemaining);
[self.locationManager stopUpdatingLocation];
}
Obecne zachowanie jest takie, że backgroundTimeRemaining
zmniejsza się z 180 sekund do zera (podczas logowania lokalizacji), a następnie program obsługi wygaśnięcia jest wykonywany i nie są generowane dalsze aktualizacje lokalizacji. Jak zmodyfikować powyższy kod, aby otrzymywać okresowe aktualizacje lokalizacji w tle na czas nieokreślony?
Aktualizacja: celuję w iOS 7 i wydaje się, że istnieją pewne dowody na to, że zadania w tle zachowują się inaczej: {]}
8 answers
Wygląda na to, że stopUpdatingLocation
jest tym, co uruchamia zegar w tle, więc zamieniłem go na didUpdateLocation
na:
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyThreeKilometers];
[self.locationManager setDistanceFilter:99999];
Co wydaje się skutecznie wyłączać GPS. Selektor tła NSTimer
staje się wtedy:
- (void) changeAccuracy {
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
}
Wszystko, co robię, to okresowe przełączanie dokładności, aby uzyskać współrzędną o wysokiej dokładności co kilka minut, a ponieważ locationManager
nie została zatrzymana, backgroundTimeRemaining
pozostaje na maksymalnej wartości. Zmniejszenie zużycia baterii od ~10% na godzinę (przy stałym kCLLocationAccuracyBest
w tle) do ~2% na godzinę na moim urządzeniu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-29 17:16:27
Napisałem aplikację za pomocą usług lokalizacji, aplikacja musi wysyłać lokalizację co 10s. I to działało bardzo dobrze.
Po prostu użyj metody "allowDeferredLocationUpdatesUntiltraveled:timeout ", zgodnie z dokumentem Apple.
Kroki są następujące:
Wymagane: Zarejestruj tryb tła dla lokalizacji aktualizacji.
1. twórz LocationManger i startUpdatingLocation, z dokładnością i odpornością filtrowaną jak cokolwiek chcesz want:
-(void) initLocationManager
{
// Create the manager object
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
_locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
_locationManager.desiredAccuracy = 45;
_locationManager.distanceFilter = 100;
// Once configured, the location manager must be "started".
[_locationManager startUpdatingLocation];
}
2. aby aplikacja była zawsze uruchamiana przy użyciu metody" allowDeferredLocationUpdatesUntiltraveled:timeout " w tle, musisz ponownie uruchomić updatingLocation z nowym parametrem, gdy aplikacja przeniesie się do tła, tak:
- (void)applicationWillResignActive:(UIApplication *)application {
_isBackgroundMode = YES;
[_locationManager stopUpdatingLocation];
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[_locationManager setDistanceFilter:kCLDistanceFilterNone];
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[_locationManager startUpdatingLocation];
}
3. App gets updatedLocations as normal with "locationManager: didUpdateLocations:" callback:
-(void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// store data
CLLocation *newLocation = [locations lastObject];
self.userLocation = newLocation;
//tell the centralManager that you want to deferred this updatedLocation
if (_isBackgroundMode && !_deferringUpdates)
{
_deferringUpdates = YES;
[self.locationManager allowDeferredLocationUpdatesUntilTraveled:CLLocationDistanceMax timeout:10];
}
}
4. ale powinieneś obsłużyć dane w "locationManager:didFinishDeferredUpdatesWithError:" callback for twój cel
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
//do something
}
5. Uwaga: myślę, że powinniśmy zresetować parametry LocationManager za każdym razem, gdy aplikacja przełącza się między trybem background/forground.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-27 07:05:06
Jeśli masz
UIBackgroundModes
w pliście z kluczemlocation
, nie musisz używać metodybeginBackgroundTaskWithExpirationHandler
. To zbędne. Również używasz go nieprawidłowo (zobacz tutaj ), ale to jest dyskusyjne, ponieważ twój plist jest ustawiony.-
Z
UIBackgroundModes location
w pliście aplikacja będzie działać w tle w nieskończoność tylko tak długo, jak działaCLLocationManger
. Jeśli wywołaszstopUpdatingLocation
w tle, aplikacja zatrzyma się i nie uruchomi ponownie.Może mógłbyś zadzwonić
beginBackgroundTaskWithExpirationHandler
tuż przed wywołaniemstopUpdatingLocation
, a następnie po wywołaniustartUpdatingLocation
możesz zadzwonić doendBackgroundTask
, aby zatrzymać go podczas zatrzymania GPS, ale nigdy tego nie próbowałem - to tylko pomysł.Inną opcją (której nie próbowałem) jest utrzymywanie menedżera lokalizacji działającego w tle, ale po uzyskaniu dokładnej lokalizacji zmień właściwość
desiredAccuracy
na 1000M lub wyższą, aby umożliwić wyłączenie układu GPS (aby zaoszczędzić baterię). Następnie 10 minut później, gdy potrzebujesz innej lokalizacji update, ZmieńdesiredAccuracy
z powrotem na 100m, aby włączyć GPS, dopóki nie uzyskasz dokładnej lokalizacji, powtórz. Kiedy dzwonisz
startUpdatingLocation
do menedżera lokalizacji, musisz dać mu czas na zdobycie stanowiska. Nie należy natychmiast dzwonićstopUpdatingLocation
. Pozwalamy mu działać maksymalnie przez 10 sekund lub do czasu uzyskania Nie buforowanej lokalizacji o wysokiej dokładności.-
Musisz odfiltrować buforowane lokalizacje i sprawdzić dokładność lokalizacji, aby upewnić się, że spełnia Twoje minimum wymagana dokładność (patrz tutaj ). Pierwsza aktualizacja może mieć 10 minut lub 10 dni. Pierwsza dokładność jaką uzyskasz może wynosić 3000m.
Zamiast tego rozważ użycie interfejsów API znaczącej zmiany lokalizacji. Po otrzymaniu powiadomienia o istotnych zmianach możesz uruchomić
CLLocationManager
na kilka sekund, aby uzyskać wysoką dokładność pozycji. Nie jestem pewien, nigdy nie korzystałem z usług zmiany lokalizacji.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:33
Gdy nadszedł czas, aby uruchomić usługę lokalizacji i zatrzymać zadanie w tle, zadanie w tle powinno zostać zatrzymane z opóźnieniem (1 sekunda powinna wystarczyć). W przeciwnym razie usługa lokalizacji nie rozpocznie się. Również usługa lokalizacji powinna być włączona na kilka sekund (np. 3 sekundy).
Istnieje CocoapodAPScheduledLocationManager , który pozwala na pobieranie aktualizacji lokalizacji w tle coN sekund z żądaną dokładnością lokalizacji.
let manager = APScheduledLocationManager(delegate: self)
manager.startUpdatingLocation(interval: 170, acceptableLocationAccuracy: 100)
Repozytorium zawiera również przykładowa aplikacja napisana w języku Swift 3.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-29 14:37:41
Może spróbujesz z startMonitoringSignificantLocationChanges:
API? Zdecydowanie strzela z mniejszą częstotliwością, a celność jest dość dobra. Dodatkowo ma o wiele więcej zalet niż używanie innych API locationManager
.
Dużo więcej o tym API zostało już omówione na tym linku
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:40
Musisz dodać tryb aktualizacji lokalizacji w aplikacji, dodając następujący klucz w informacji.plist.
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
didUpdateToLocation
metoda zostanie wywołana (nawet gdy aplikacja jest w tle). Możesz wykonać dowolną rzecz na podstawie wywołania tej metody
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-27 05:28:01
Ten projekt będzie działał do zarządzania lokalizacją w tle.
Będzie zarządzać automatycznie, jeśli aplikacja wejdzie w tło i trzeba wysłać połączenie sieciowe, aby zaktualizować lokalizację.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-27 18:34:47
Po iOS 8 ich jest kilka zmian w corelocation framework związane pobieranie tła i aktualizacje wykonane przez apple.
1) Apple wprowadza zawsze prośbę autoryzacji o pobranie aktualizacji lokalizacji w aplikacji.
2) Apple wprowadza backgroundLocationupdates do pobierania lokalizacji z tła w systemie iOS.
Aby pobrać lokalizację w tle, musisz włączyć aktualizację lokalizacji w możliwościach Xcode.
//
// ViewController.swift
// DemoStackLocation
//
// Created by iOS Test User on 02/01/18.
// Copyright © 2018 iOS Test User. All rights reserved.
//
import UIKit
import CoreLocation
class ViewController: UIViewController {
var locationManager: CLLocationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
startLocationManager()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
internal func startLocationManager(){
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startUpdatingLocation()
}
}
extension ViewController : CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
let location = locations[0] as CLLocation
print(location.coordinate.latitude) // prints user's latitude
print(location.coordinate.longitude) //will print user's longitude
print(location.speed) //will print user's speed
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-02 12:28:08