当前位置: 首页 > 知识库问答 >
问题:

定期更新iOS后台位置

岳亮
2023-03-14

我正在编写一个应用程序,需要高精度和低频率的背景位置更新。解决方案似乎是一个后台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中的位置管理器

共有3个答案

於乐
2023-03-14

>

使用plist中的UIBackgroundModes location,只有在cllocationmanager运行时,应用程序才会无限期地在后台运行。如果您在后台调用stopUpdateLocation,则应用程序将停止,不再启动。

也许你可以在调用停止更新位置之前调用starUpdatingPlace,然后在调用starUpdatingPlace之后,调用endBack接地任务,在全球定位系统停止时保持其背景,但我从未尝试过-只是一个想法。

另一个选项(我没有尝试过)是在后台保持位置管理器运行,但一旦获得准确位置,请将desiredAccuracy属性更改为1000m或更高,以允许GPS芯片关闭(以节省电池)。然后10分钟后,当您需要另一个位置更新时,将desiredAccuracy更改回100m以打开GPS,直到获得准确位置,然后重复。

当您在location manager上调用startUpdatingLocation时,您必须给它时间来获得一个职位。您不应该立即调用停止更新位置。我们让它运行最多10秒,或者直到我们得到一个非缓存的高精度位置。

您需要过滤掉缓存的位置,并检查您获得的位置的准确性,以确保它符合您要求的最低精度(请参阅此处)。你得到的第一个更新可能是10分钟或10天前。你得到的第一个准确度可能3000m。

考虑使用显著的位置改变API。收到重大更改通知后,您可以启动CLLocationManager几秒钟以获得高精度位置。我不确定,我从未使用过重要的位置更改服务。

鲁淇
2023-03-14

我写了一个应用程序使用定位服务,应用程序必须发送位置每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的参数。

王刚毅
2023-03-14

它似乎是触发后台看门狗计时器,所以我在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跟踪器图标一直都在。