我正在寻找一种在iOS应用程序中每n分钟更新一次后台位置的方法.我正在使用iOS 4.3,该解决方案适用于非越狱的iPhone.
我尝试/考虑了以下选项:
CLLocationManager startUpdatingLocation/startMonitoringSignificantLocationChanges
:这根据预期在后台工作,基于配置的属性,但似乎不可能强制它每n分钟更新一次位置NSTimer
:当应用程序在前台运行但似乎不是为后台任务设计时,是否有效UIApplication:beginBackgroundTaskWithExpirationHandler
:据我所知,当应用程序移动到后台而不是实现"长时间运行"的后台进程时,这应该用于在后台完成一些工作(也限制时间).如何实施这些常规后台位置更新?
这是CLLocationManager文档中描述使用startMonitoringSignificantLocationChanges的应用程序行为的部分:
如果您启动此服务并且您的应用程序随后终止,则系统会在新事件到达时自动将应用程序重新启动到后台.在这种情况下,传递给应用程序的选项字典:didFinishLaunchingWithOptions:应用程序委托的方法包含密钥UIApplicationLaunchOptionsLocationKey,以指示您的应用程序是由于位置事件而启动的.重新启动后,您仍必须配置位置管理器对象并调用此方法以继续接收位置事件.重新启动位置服务时,会立即将当前事件传递给您的代理.此外,即使在启动位置服务之前,也会使用最新的位置对象填充位置管理器对象的位置属性.
所以我的理解是,如果你的应用程序终止(并假设你没有从applicationWillTerminate调用stopMonitoringSignificantLocationChanges),你将会被应用程序唤醒UIApplicationLaunchOptionsLocationKey参数:didFinishLaunchingWithOptions.此时,您将创建CLLocationManager,调用startMonitoringSignificantLocationChanges并在有限时间内执行后台位置处理.这一点我很好.
前一段只谈到应用程序终止时会发生什么,它不会建议您在应用程序暂停时执行的操作.didFinishLaunchingWithOptions的文档说:
该应用程序在后台跟踪位置更新,已被清除,现在已重新启动.在这种情况下,字典包含一个键,表示由于新的位置事件导致应用程序重新启动.
建议您在终止后启动应用程序(因为位置更改)时才会收到此呼叫.
但是," 位置感知规划指南"中关于重大变更服务的段落如下:
如果您使此服务保持运行并且您的应用程序随后被暂停或终止,则服务会在新位置数据到达时自动唤醒您的应用程序.在唤醒时,您的应用程序将被置于后台并给予少量时间来处理位置数据.由于您的应用程序位于后台,因此应该执行最少的工作并避免任何可能阻止其在分配的时间到期之前返回的任务(例如查询网络).如果没有,您的申请可能会被终止.
这表明如果您的应用已被暂停,您会被位置数据唤醒,但未提及您是如何被唤醒的:
在写这篇文章的过程中,我想我可能刚刚回答了我自己的问题,但是如果有更多知识渊博的人对我的理解得到证实,那就太棒了.
有没有办法手动告诉设备发送重要的位置变更通知,该通知会唤醒为此通知注册的任何应用程序?这仅用于测试,我意识到这个私有API调用在提交到应用商店时会被拒绝.
2014年初,Apple已将iOS 7.0更新为7.1,以便即使应用程序在前台而非后台处于活动状态时也允许位置更新.我们怎么做?
我读过一些文章,比如Apple的iOS 7.1将修复地理定位错误.但是,即使应用程序被终止/终止/暂停,Apple也没有提供与此相关的任何通信,也没有提供有关如何获取位置更新的示例代码.
我已阅读iOS 7.1发行说明.我也找不到任何相关的东西.
那么,即使应用程序被暂停,我们如何实际获得iOS 7和8的位置更新?
似乎在iOS 7中,应用程序无法再从后台任务启动位置管理器(通过调用startUpdatingLocation).
在iOS 6中,我使用了这里描述的方法:https://stackoverflow.com/a/6465280每n分钟运行一次后台位置更新.我们的想法是使用计时器运行后台任务,并在计时器触发时启动位置管理器.之后关闭位置管理器并启动另一个后台任务.
更新到iOS 7后,此方法不再起作用.启动位置管理器后,应用程序不会收到任何locationManager:didUpdateLocations.有任何想法吗?
我正在尝试测试区域监控,因为我正在获得这样的当前位置:
- (void)startLocationTracking
{
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
// Start location manager
if ([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
locationManager = [LocationTracker sharedLocationManager];
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];
}
}
Run Code Online (Sandbox Code Playgroud)
并跟踪区域监控的第一个位置,如下所示:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:manager.location.coordinate radius:300 identifier:@"first location initializer"];
NSLog(@"0: %@", manager.location);
NSLog(@"1: %@", region);
[manager startMonitoringForRegion:region];
NSLog(@"[locationManager startMonitoringForRegion:%@];", region);
});
}
Run Code Online (Sandbox Code Playgroud)
然后在当前区域的每个出口处,我正在监视新位置,如下所示:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"%s, %@", __PRETTY_FUNCTION__, region);
} …
Run Code Online (Sandbox Code Playgroud) 问候所有.
我正在尝试将重要的位置更改和区域支持实施到我的应用中.当应用程序处于活动状态时,接收位置更新显然没有问题.我的问题是如何在应用程序未处于活动状态时处理更新.
这是我对如果检测到重要位置更改或区域进入/退出会发生什么的理解:
它是否正确?我错过了什么吗?
感谢帮助.
问候, - 约翰
我想让我的应用程序监视器在手机锁定和解锁时,以及当它变为空白(经过较长时间不活动)后,这一切都在我的应用程序没有聚焦,但在后台运行时.
在应用专注时,我可以轻松收到锁定/解锁/空白事件:
-(void) startListeningForPhoneLockEvent
{
NSLog(@"Start listening to lock/unlock and screen-goes-black events.");
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
(void*)self,
lockStateChanged,
CFSTR("com.apple.springboard.lockstate"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
(void*)self,
hasBlankedScreen,
CFSTR("com.apple.springboard.hasBlankedScreen"),
NULL,
CFNotificationSuspensionBehaviorDeliverImmediately);
}
Run Code Online (Sandbox Code Playgroud)
和回调函数:
static void lockStateChanged( CFNotificationCenterRef center, void*observer, CFStringRef name, const void *object, CFDictionaryRef userInfo )
{
NSLog(@"Lock event received!");
}
static void hasBlankedScreen( CFNotificationCenterRef center, void*observer, CFStringRef name, const void *object, CFDictionaryRef userInfo )
{
NSLog(@"Blanked screen event received!");
}
Run Code Online (Sandbox Code Playgroud)
我启用了后台模式:
但是,一旦应用程序进入后台,它就不会收到锁定/解锁/空白屏幕事件.
我尝试过其他背景模式,如声音播放,位置更新等,但应用程序仍然没有在后台接收锁定/解锁/空白屏幕事件.
我不确定这是否真的可行,或者我做错了什么.
我正在使用最新的XCode和iOS9 SDK在真实设备上测试它,该设备已更新到iOS9.
我一直在努力实现步行,骑自行车和驾驶的路线追踪图.
但是,正如您在下面的屏幕截图中看到的那样,即使我没有步行/骑自行车或驾驶该位置,我的坐标也会不时突然跳起.已在图像上绘制圆圈以指出问题.我的问题是为什么突然坐标跳跃?
这是我的实现快照:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
CoordinateModel *coord = [[CoordinateModel alloc] init];
coord.latitude = newLocation.coordinate.latitude;
coord.longitude = newLocation.coordinate.longitude;
ActivityType currentActivityType = [DataManager sharedInstance].activityType;
if (currentActivityType == 0) {
// walking
[appDelegate.walkingCoordinates addObject:coord];
}
else if(currentActivityType == 1) {
[appDelegate.bikingCoordinates addObject:coord];
}
else if(currentActivityType == 2) {
// driving
[appDelegate.drivingCoordinates addObject:coord];
}
self.coordinate = newLocation.coordinate;
}
Run Code Online (Sandbox Code Playgroud) ios ×9
objective-c ×6
iphone ×2
background ×1
clregion ×1
events ×1
ios7 ×1
location ×1
xcode ×1