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

在应用程序进入后台后,每隔n分钟获取用户位置

柯甫
2023-03-14

我正在努力实施这篇文章中给出的建议。

不幸的是,我不清楚步骤。我尝试实施这些建议,但后台时间剩余继续减少,即使我开始和停止位置服务。我是这样开发它的:

- (void)applicationDidEnterBackground:(UIApplication *)application {

    UIApplication*    app = [UIApplication sharedApplication];

    bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // Do the work associated with the task.
        self.timer = nil;
        [self initTimer];

    });
}

InitTimer:

- (void)initTimer {

    // Create the location manager if this object does not
    // already have one.
    if (nil == self.locationManager)
        self.locationManager = [[CLLocationManager alloc] init];

    self.locationManager.delegate = self;
    [self.locationManager startMonitoringSignificantLocationChanges];

    if (self.timer == nil) {
        self.timer = [NSTimer scheduledTimerWithTimeInterval:0.3
                                              target:self
                                            selector:@selector(checkUpdates:)
                                            userInfo:nil
                                             repeats:YES];
    }
}

检查更新:

- (void)checkUpdates:(NSTimer *)timer{
    UIApplication*    app = [UIApplication sharedApplication];
    double remaining = app.backgroundTimeRemaining;
    if(remaining < 580.0) {
        [self.locationManager startUpdatingLocation]; 
        [self.locationManager stopUpdatingLocation]; 
        [self.locationManager startMonitoringSignificantLocationChanges];
    }
    DbgLog(@"Reminaing %f", app.backgroundTimeRemaining);
}

有人对我的代码中可能出现的错误有什么建议吗?正在调用initTimer和checkUpdates,但仅在后台执行时间(-10分钟)期间调用。我希望应用程序“永远”每隔n分钟更新一次位置。

我的应用程序的UIBackgroundModes设置为location。

更新:

我现在正在重置didUpdateToLocation和didFailWithError上的计时器。但剩余的背景时间仍在减少:

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

NSLog(@"Did Update Location = %f / %f", [newLocation coordinate].latitude, [newLocation coordinate].longitude);

UIApplication*    app = [UIApplication sharedApplication];

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Do the work associated with the task.

    [self initTimer];

});
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {

[self.locationManager stopUpdatingLocation]; 
UIApplication*    app = [UIApplication sharedApplication];

bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
    [app endBackgroundTask:bgTask];
    bgTask = UIBackgroundTaskInvalid;
}];

// Start the long-running task and return immediately.
[self initTimer];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Do the work associated with the task.

});

}

我还使计时器无效:

- (void)checkUpdates:(NSTimer *)timer{
UIApplication*    app = [UIApplication sharedApplication];
double remaining = app.backgroundTimeRemaining;
if(remaining < 580.0 && remaining > 570.0) {
    [self.timer invalidate];
    self.timer = nil;
    [self.locationManager startUpdatingLocation]; 
    [self.locationManager stopUpdatingLocation]; 
}
DbgLog(@"*************************Checking for updates!!!!!!!!!!! Reminaing %f", app.backgroundTimeRemaining);
}

共有3个答案

慕容聪
2023-03-14

一旦你在后台,你只能有10分钟的额外时间。没有办法扩大这一点。您应该改用位置后台服务。

姜磊
2023-03-14

经过几天尝试所有可能的解决方案,我终于能够使它工作。以下是我的解决方案中的错误:

  • 我需要设置2个UIBackground任务标识符,一个用于定时器,另一个用于locationManager

在我的解决方案中,只需添加

UIApplication *app = [UIApplication sharedApplication];

bgTask2 = [app beginBackgroundTaskWithExpirationHandler:^{ 
[app endBackgroundTask:bgTask2]; 
bgTask2 = UIBackgroundTaskInvalid; }];

self.locationManager.delegate = self; 
[self.locationManager startUpdatingLocation]; 
徐淳
2023-03-14

对于任何一个正在经历噩梦的人来说,我有一个简单的解决方案。

>

  • 学习raywenderlich的例子。通用域名格式。示例代码工作得很好,但不幸的是,在后台定位期间没有计时器。这将无限期地运行
  • 使用以下代码段添加计时器:

    -(void)applicationDidEnterBackground {
      [self.locationManager stopUpdatingLocation];
    
      UIApplication* app = [UIApplication sharedApplication];
    
      bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
      }];
    
      self.timer = [NSTimer scheduledTimerWithTimeInterval:intervalBackgroundUpdate
                                                    target:self.locationManager
                                                  selector:@selector(startUpdatingLocation)
                                                  userInfo:nil
                                                   repeats:YES];
    }
    

    别忘了在info.plist.中添加“位置更新应用注册”

  •  类似资料:
    • 我正试图通过后台获取从url获取数据。My func尝试获取数据,如果有新数据,它会发送本地通知。当我最小化应用程序时,背景提取在大约10-20分钟后工作。但当我关闭应用程序(双击home按钮并关闭应用程序)时,它就不起作用了。我等了大约一个小时,但没有成功。我正在Android系统中使用后台服务,它正在成功运行。当应用程序关闭时,有没有办法从url获取数据并发送本地通知?我使用的是Xcode 6

    • 我有一个博览会应用程序,我需要在后台运行地理Geofence,即使应用程序关闭。我得到的纬度和经度发送通过消息推送这样从C#应用程序。 PushBody=数据。说明“[ 任务是,如果手机位于提供的坐标中,我需要显示推送通知 我的App.js档案是这样的 我已经取得了权限,我需要一个解决方案,在后台运行位置服务,并显示推送通知,如果手机是在纬度和经度之间,我收到推送通知 如果有人帮我,我会非常感激的

    • 大家好,耶稣受难节, 我知道这似乎是一个重复的问题,但事实并非如此,我将向您解释原因: 有几种方法可以在计划的时间执行任务,如TimerTask或ScheduleExecutorService,但它们都不适合我要做的事情,因为这些方法都是这样工作的: -- 但我不希望我的代码在计划时间后一次又一次地运行,我希望我的代码总是在每个计划时间执行,即使是第一次。 还有一个问题:如果android停止后台

    • 我正在开发一个Android应用程序,有一个不断重复的后台进程。 从设备启动的那一刻起,它应该每分钟加载一个网页上的数据。它使用XmlPullParser和一个简单的URL InputStream。它只有10KB,所以没有那么密集。我相信这种任务叫做延期。一旦用户打开应用程序,流程加载的信息必须可以访问活动。后台进程也需要设置,以便在数据显示某些结果时发出通知。 在Android中似乎有多种方法来

    • 即使应用程序在后台,我也需要每5分钟在Android应用程序中运行一次代码。我对android Studio知之甚少,比如将代码放在哪里,以及如何正确执行以避免在后台时崩溃和不同的错误。 该应用程序是一个网络视图,从站点代码中提取JS的Id,然后我需要每隔5分钟运行一个带有该Id的脚本。