ios - por - ¿Cómo rastrear la ubicación del usuario en segundo plano?
localizar iphone por gps (8)
Estoy buscando una aplicación de código abierto o una biblioteca para rastrear la ubicación del usuario en segundo plano. Ahora trato de hacerlo con CLLocation
y tareas en segundo plano, pero la precisión no es suficiente para mi caso. ¿Podría explicar cómo las aplicaciones, como "se mueve", "runkeeper", "endmondo", crean mi ruta? ¿Debo usar el acelerómetro y / o la brújula para crear una ruta entre los puntos de fondo de CLLocation?
Algún código:
//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 probó mi aplicación con las siguientes propiedades
self.locationManager.distanceFilter = kCLDistanceFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.activityType = CLActivityTypeFitness;
self.locationManager.pausesLocationUpdatesAutomatically=NO;
En este caso tengo alrededor de 10 eventos disparados durante 1,5 horas de viaje.
Aquí estaba mi solución a esto,
Declara la variable de instancia:
CLLocationManager *locationManager;
Asegúrate de incluir al delegado
<CLLocationManagerDelegate>
En 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];
Implementar el método delegado:
- (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;
}
Así que su aplicación utiliza servicios de ubicación. A continuación, lea la Guía de programación para el conocimiento de la ubicación .
Necesitas hacer algunos cambios en tu Info.plist:
- Si su aplicación depende de los servicios de ubicación para funcionar correctamente, agregue los servicios de ubicación a UIRequiredDeviceCapabilities
- Si su aplicación requiere hardware GPS, agregue gps a UIREquedadoDeviceCapabilities
- Si necesita ejecutar su aplicación durante más de 10 minutos en segundo plano, agregue la ubicación a UIBackgroundModes. Luego, su administrador de ubicación entregará ubicaciones más allá del límite de 10 minutos.
- también debe configurar NSLocationUsageDescription (también se puede localizar)
Obtención de eventos de ubicación en el fondo
Si su aplicación necesita actualizaciones de ubicación, ya sea que la aplicación esté en primer plano o en segundo plano, existen múltiples opciones para hacerlo. La opción preferida es usar el servicio de cambio de ubicación significativo para activar su aplicación en momentos apropiados para manejar nuevos eventos. Sin embargo, si su aplicación necesita utilizar el servicio de ubicación estándar, puede declarar que necesita servicios de ubicación en segundo plano.
Una aplicación debe solicitar servicios de ubicación en segundo plano solo si la ausencia de esos servicios perjudicaría su capacidad para operar. Además, cualquier aplicación que solicite servicios de ubicación en segundo plano debe usar esos servicios para proporcionar un beneficio tangible para el usuario. Por ejemplo, una aplicación de navegación paso a paso sería un candidato probable para los servicios de ubicación en segundo plano debido a su necesidad de rastrear la posición del usuario e informar cuándo es el momento de dar el siguiente giro.
Debe agregar en su archivo "Info.plist" la clave UIBackgroundModes
(matriz) con el valor "ubicación" (la aplicación se registra para las actualizaciones de ubicación). Puedes consultar todos los modos de fondo here .
Descargo de responsabilidad: trabajo para Cintric
También queríamos poder realizar un seguimiento preciso de la ubicación de los usuarios en segundo plano (incluso después de que la aplicación hubiera sido eliminada). Pasamos mucho tiempo resolviendo el problema, especialmente centrándonos en el consumo de la batería.
Publicamos una gran publicación en el blog sobre cómo lo resolvimos. Y también están proporcionando una solución SDK de arrastrar y soltar. No es de código abierto pero puedes integrarlo gratis:
Puede descargar el archivo .framework, arrastrarlo a su proyecto e inicializarlo con una línea de código: [CintricFind initWithApiKey:@"YOUR_API_KEY_HERE" andSecret:@"YOUR_SECRET_HERE"];
Puede obtener una clave API de forma gratuita. Hay documentos explicando todo here .
Puede configurar las cosas de ubicación de monitoreo en su VC de la siguiente manera
en el método viewDidLoad haga lo siguiente
CLLocationManager locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;(Accuracy according to your need)
[locationManager startUpdatingLocation];
de lo que tiene que sobrescribir debajo de los dos métodos de delegado opcionales del protocolo CLLocationManagerDelegate
para iOS6 +
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{}
y para iOS 2 a 6
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
En estos métodos obtendrá la ubicación actualizada. Úsalo como quieras. Cada vez que se actualiza la ubicación de este método se obtienen llamadas.
Su problema es el controlador de fondo. Quítelo y habilite el modo gps background en el archivo plist. entonces deberías obtener gps de potencia completa todo el tiempo.
Establecer propiedad pausesLocationUpdatesAutomatically=NO
Esto es nuevo en ios6.
Desde CLLocationManager :
Permitir que el administrador de ubicación haga una pausa en las actualizaciones puede mejorar la vida útil de la batería en el dispositivo de destino sin sacrificar los datos de ubicación. Cuando esta propiedad se establece en SÍ, el administrador de ubicación detiene las actualizaciones (y apaga el hardware apropiado) en los momentos en que es poco probable que los datos de ubicación cambien. Por ejemplo, si el usuario deja de comer mientras usa una aplicación de navegación, el administrador de ubicación puede pausar las actualizaciones por un período de tiempo. Puede ayudar a determinar cuándo pausar las actualizaciones de ubicación asignando un valor a la propiedad activityType.
El valor predeterminado de esta propiedad es SÍ.
Para el análisis, agregue estos métodos a su delegado de LocationManager:
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager {
NSLog(@"locMan: locationManagerDidPauseLocationUpdates");
}
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager {
NSLog(@"locMan: locationManagerDidResumeLocationUpdates");
}