我正在编写一个应用程序,需要高精度和低频率的背景位置更新。解决方案似乎是一个后台NSTimer任务,它启动location manager的更新,然后立即关闭。这个问题以前有人问过:
如何在iOS应用程序中每n分钟更新一次后台位置?
在应用程序进入后台后每n分钟获取一次用户位置
iOS不是典型的后台位置跟踪计时器问题
iOS长时间运行的后台计时器,具有“位置”后台模式
基于位置跟踪的iOS全职后台服务
但我还没有找到一个最起码的例子。在尝试了上述被接受的答案的每一种排列之后,我把一个起点放在了一起。进入背景:
- (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];
}
和委托方法:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"%@", newLocation);
NSLog(@"background time: %f", [UIApplication sharedApplication].backgroundTimeRemaining);
[self.locationManager stopUpdatingLocation];
}
当前的行为是,背景时间剩余
从180秒减到零(同时记录位置),然后过期处理程序执行,不再生成进一步的位置更新。如何修改上述代码,以便在后台无限期接收定期位置更新?
更新:我的目标是iOS7,似乎有一些证据表明后台任务的行为不同:
从后台任务启动iOS 7中的位置管理器
>
使用plist中的UIBackgroundModes location
,只有在cllocationmanager
运行时,应用程序才会无限期地在后台运行。如果您在后台调用stopUpdateLocation
,则应用程序将停止,不再启动。
也许你可以在调用停止更新位置之前调用starUpdatingPlace
,然后在调用starUpdatingPlace
之后,调用endBack接地任务
,在全球定位系统停止时保持其背景,但我从未尝试过-只是一个想法。
另一个选项(我没有尝试过)是在后台保持位置管理器运行,但一旦获得准确位置,请将desiredAccuracy
属性更改为1000m或更高,以允许GPS芯片关闭(以节省电池)。然后10分钟后,当您需要另一个位置更新时,将desiredAccuracy
更改回100m以打开GPS,直到获得准确位置,然后重复。
当您在location manager上调用startUpdatingLocation
时,您必须给它时间来获得一个职位。您不应该立即调用停止更新位置
。我们让它运行最多10秒,或者直到我们得到一个非缓存的高精度位置。
您需要过滤掉缓存的位置,并检查您获得的位置的准确性,以确保它符合您要求的最低精度(请参阅此处)。你得到的第一个更新可能是10分钟或10天前。你得到的第一个准确度可能3000m。
考虑使用显著的位置改变API。收到重大更改通知后,您可以启动CLLocationManager
几秒钟以获得高精度位置。我不确定,我从未使用过重要的位置更改服务。
我写了一个应用程序使用定位服务,应用程序必须发送位置每10秒。而且效果非常好。
只需使用“AllowDeferredLocationUpdatesUntiltTraveled:timeout”方法,遵循Apple的文档。
步骤如下:
必需:注册后台模式以更新位置。
1.创建LocationManager和startUpdatingLocation,精确度和过滤器添加量随您的需要而定:
-(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.要在后台使用“AllowDeferredLocationUpdatesUntiltTraveled:timeout”方法保持应用程序永远运行,当应用程序移动到后台时,必须使用新参数重新启动UpdateLocation,如下所示:
- (void)applicationWillResignActive:(UIApplication *)application {
_isBackgroundMode = YES;
[_locationManager stopUpdatingLocation];
[_locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[_locationManager setDistanceFilter:kCLDistanceFilterNone];
_locationManager.pausesLocationUpdatesAutomatically = NO;
_locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[_locationManager startUpdatingLocation];
}
3.应用程序获取更新位置作为正常"locationManager: didUpdateLocations:"回调:
-(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.但是你应该在“locationManager: didFinishDeferredUpdatesAnd Error:”回调中处理数据
- (void) locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error {
_deferringUpdates = NO;
//do something
}
5.注意:我认为每次应用程序在后台/后台模式之间切换时,我们都应该重置LocationManager的参数。
它似乎是触发后台看门狗计时器,所以我在didUpdatePlace中替换为:
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyThreeKilometers];
[self.locationManager setDistanceFilter:99999];
这似乎有效地切断了GPS的电源。然后,后台NSTimer
的选择器变为:
- (void) changeAccuracy {
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kCLDistanceFilterNone];
}
我所做的只是周期性地切换精度,以每隔几分钟获得一个高精度坐标,因为locationManager
没有被停止,所以background ground TimeRemning
保持在其最大值。在我的设备上,这将电池消耗从每小时〜10%(后台有恒定的kCLLocationAccuracyBest
)降低到每小时〜2%。
我正在开发一个android应用程序,我需要在后台使用GPS提供商获得更长时间的位置更新,所以当用户不再与它交互时,我需要位置更新。我自己做了一些测试,比较LocationManager的requestSingleUpdate(provider,pendingIntent版本)和requestLocationUpdates(provider,minTime,minDistance,intent版本
我的背景粘性服务是杀死奥利奥和更高的设备,任何解决方案,以获得位置的背景服务时,活动是在后台
问题内容: 我是这里的新用户,但是我已经使用stackoverflow很多次了:)…我是android开发人员,但是现在我正在使用swift在ios应用程序中工作。我对使用xcode完全陌生,也许我的问题在很多方面都很简单…太好了,我真的需要帮助。我正在尝试实现一个背景任务,该任务每十分钟更新一次用户位置。我需要获取经纬度数据,并将此信息发送到API网络服务。我一直在介绍backgroud文档,所
问题内容: 我必须使用Swift 3在iOS中制作一个应用程序,该应用程序在后台运行时每3或5分钟通过API发送一次用户的位置信息。我不知道哪种方法是最好的方法,或者由于苹果严格的背景规定,是否有可能这样做。该位置必须非常精确,并且该应用需要在背景下长时间运行,可能不会消耗太多电池。如果不可能,那么很高兴知道在这种情况下哪种方法最好。非常感谢你。 问题答案: 该应用程序在后台运行时每3或5分钟通过
我正在构建一个在后台工作的iOS应用程序,并每3分钟将用户的位置发布到服务器上(因为这是iOS 7上的最长后台执行时间)。但是,有一个问题,后台服务在随机时间终止。所以有时候它可以在后台运行2个小时,有时候7个小时,然后3个小时,然后是随机的,依此类推。 下面的代码产生错误。我已经能够检测到它何时终止,也就是[UIApplication sharedApplication]何时终止。剩余的背景时间
我正在制作一个定期采样数据的应用程序。由于某种原因,我无法获得GPS数据。以下是我得到的: 舱单: 我想重申,我没有问题与空位置,函数没有得到调用。 我在外面走了几分钟的时候测试了这个代码,所以卫星接收不是问题。GPS跟踪器图标一直都在。