我正在开发一个示例应用程序来跟踪用户在后台的位置,但我不想让定位服务始终处于启用状态,但我的计时器中的某些内容无法正常运行。
我的想法是,每隔 x 分钟,服务就会继续,当它有一个正确的新位置时,它会再次发布,现在设置为 10 秒,仅用于测试。(显着的 LocationChange 不是诀窍,不够准确)
我搜索了很多(iOS 开发中心 + StackOverflow)并找到了“新的”后台定位功能,它允许您在进入后台后 10 分钟内运行代码,使用 beginBackgroundTaskWithExpirationHandler、几个块和一个计时器。
我将后台模式设置为位置,现在我认为我不需要处理后台时间的结束(首先我想每 15-20 秒获取一次位置)
代码工作“正常”但是:
- 计时器有时会触发,有时不会。
- 当计时器触发时,它至少需要 10 分钟才能完成。
- 操作系统中的一些随机操作(例如进入搜索桌面)似乎可以估计计时器触发(不确定这一点,我不知道它是如何可能的,但它是......)
而通过代码将是另一个问题。
appdelegates 的方法:
// applicationDidEnterBackground
- (void)applicationDidEnterBackground:(UIApplication *)application{
NSLog(@"to background");
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.
_triggertimer = nil;
[self initTimer];
});
NSLog(@"backgroundTimeRemaining: %.0f", [[UIApplication sharedApplication] backgroundTimeRemaining]);}
//初始化定时器
- (void) initTimer{
NSLog(@"InitTimer ");
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
_triggertimer = [NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:@selector(checkUpdates:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_triggertimer forMode:NSDefaultRunLoopMode] ;
[[NSRunLoop currentRunLoop] run];
}];}
//检查更新
- (void)checkUpdates:(NSTimer *)timer{
NSLog(@"CheckUpdates ");
UIApplication* app = [UIApplication sharedApplication];
if (nil == _locationManager) _locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
_locationManager.distanceFilter = 10;
_locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
[_locationManager startUpdatingLocation];
[_locationManager startMonitoringSignificantLocationChanges];
double remaining = app.backgroundTimeRemaining;
NSLog(@"Reminaing %f", remaining);}
我尝试了很多东西来解决这个问题,也许我搞砸了或错过了一些东西......你看到了什么?也许是一些概念错误,我正在尝试向这些块介绍自己,但我还没有对它们进行分类 ¬¬
顺便说一句,为什么在使用beginBackgroundTaskWithExpirationHandler做任何事情之前我发现的所有代码都包含这个?
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
我以为这是为了拍摄 600 秒的背景……但我不确定!