我最近升级了我的 iOS 设备以使用 iOS 7。我们正在开发的应用程序之一使用后台定位服务来跟踪设备位置,我们所有的测试人员都报告说该应用程序似乎不再在 iOS 下在后台进行跟踪7.
我们已经验证在设备的设置中启用了应用程序的后台,并且之前的构建在 iOS 6 下完美运行。即使设备被循环,应用程序也会在位置更新后重新启动。
在 iOS 7 下是否需要做其他事情才能使这项工作?
我最近升级了我的 iOS 设备以使用 iOS 7。我们正在开发的应用程序之一使用后台定位服务来跟踪设备位置,我们所有的测试人员都报告说该应用程序似乎不再在 iOS 下在后台进行跟踪7.
我们已经验证在设备的设置中启用了应用程序的后台,并且之前的构建在 iOS 6 下完美运行。即使设备被循环,应用程序也会在位置更新后重新启动。
在 iOS 7 下是否需要做其他事情才能使这项工作?
这是我用来从 iOS 7 设备获取连续位置的解决方案,无论它是在前台还是后台。
您可以从博客和 github 中找到完整的解决方案和解释:-
方法和说明:-
我在函数didUpdateLocations中每 1 分钟重新启动一次位置管理器
我允许位置管理器在关闭设备之前从设备获取位置 10 秒钟(以节省电池)。
部分代码如下:-
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
for(int i=0;i<locations.count;i++){
CLLocation * newLocation = [locations objectAtIndex:i];
CLLocationCoordinate2D theLocation = newLocation.coordinate;
CLLocationAccuracy theAccuracy = newLocation.horizontalAccuracy;
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 30.0)
continue;
//Select only valid location and also location with good accuracy
if(newLocation!=nil&&theAccuracy>0
&&theAccuracy<2000
&&(!(theLocation.latitude==0.0&&theLocation.longitude==0.0))){
self.myLastLocation = theLocation;
self.myLastLocationAccuracy= theAccuracy;
NSMutableDictionary * dict = [[NSMutableDictionary alloc]init];
[dict setObject:[NSNumber numberWithFloat:theLocation.latitude] forKey:@"latitude"];
[dict setObject:[NSNumber numberWithFloat:theLocation.longitude] forKey:@"longitude"];
[dict setObject:[NSNumber numberWithFloat:theAccuracy] forKey:@"theAccuracy"];
//Add the vallid location with good accuracy into an array
//Every 1 minute, I will select the best location based on accuracy and send to server
[self.shareModel.myLocationArray addObject:dict];
}
}
//If the timer still valid, return it (Will not run the code below)
if (self.shareModel.timer)
return;
self.shareModel.bgTask = [BackgroundTaskManager sharedBackgroundTaskManager];
[self.shareModel.bgTask beginNewBackgroundTask];
//Restart the locationMaanger after 1 minute
self.shareModel.timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self
selector:@selector(restartLocationUpdates)
userInfo:nil
repeats:NO];
//Will only stop the locationManager after 10 seconds, so that we can get some accurate locations
//The location manager will only operate for 10 seconds to save battery
NSTimer * delay10Seconds;
delay10Seconds = [NSTimer scheduledTimerWithTimeInterval:10 target:self
selector:@selector(stopLocationDelayBy10Seconds)
userInfo:nil
repeats:NO];
}
2014 年 5 月更新:我收到了一些请求,要求在特定时间间隔内将位置发送到服务器时添加示例代码。我已经添加了示例代码,并且还结合了 BackgroundTaskManager 的修复程序,以解决后台长时间运行的故障。如果您有任何问题,欢迎在这里加入我们的讨论:iOS 7 的后台位置更新编程与服务器位置更新讨论
2015 年 1 月更新:如果您想在应用程序暂停时获取位置更新,请参阅:即使在暂停时也为 iOS 应用程序获取位置更新
如果您查看 WWDC 2013 会议视频 #204 - What's new with multitasking pdf,第 15 页清楚地提到如果用户从应用程序切换器中删除应用程序,应用程序将不会在后台启动。请看图,
我认为他们进行了优化(可能使用运动传感器),以检测手机的“相对”静止定位并停止位置更新。这只是一个猜测,但我的测试目前显示:
我记录的数据显示地理更新在大约 15m 和 30s 之后停止。这样,您所做的所有其他后台处理也将终止。
我的设备是装有 iOS 7 的 iPhone 5。
我有 95% 的把握,在 iOS 6/6.1 上并非如此。在过去,以 100m 的精度获取地理更新可以让您在后台几乎连续运行。
更新
如果您每 8 分钟重新启动一次位置管理器,它应该会连续运行。
更新#2
我最近没有对此进行测试,但这就是我在写这篇文章时重新启动它的方式。我希望这是有帮助的。
- (void)tryRestartLocationManager
{
NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
int seconds = round(floor(now - locationManagerStartTimestamp));
if ( seconds > (60 * 8) ) {
[locationManager stopUpdatingLocation];
[locationManager startUpdatingLocation];
locationManagerStartTimestamp = now;
}
}
我的一个 iOS 应用程序需要定期向服务器发送位置更新,并且以下方法对我们有用....
从 iOS 7 开始:
所以,不要随时停止位置更新......相反,更喜欢使用必要的精度(精细位置与粗略位置)。粗略的位置不会消耗太多电池......所以这个解决方案可以解决您的问题。
在网上搜索了很多之后,找到了一个为iOS 7提供可行解决方案的链接。解决方案如下:
并确保将以下内容添加到应用程序的 Info.plist “location” 到 UIBackgroundModes 键 “location-services” 和 “gps” 到 UIRequiredDeviceCapabilities 键
学分: http: //gooddevbaddev.wordpress.com/2013/10/22/ios-7-running-location-based-apps-in-the-background/
我从后台任务Sash 中找到了另一个线程Start Location Manager in iOS 7提到
我找到了问题/解决方案。当需要启动定位服务和停止后台任务时,应该延迟停止后台任务(我设置为 1 秒)。否则定位服务将无法启动。
任何人都可以尝试并验证吗?
Nikolay,你能把你的代码贴在这里吗?我尝试每 8 分钟重新启动一次位置管理器,但它不会连续运行。
更新:
经过高低搜索,我从苹果论坛找到了解决方案!
在 iOS 7 中,您无法在后台启动定位服务。如果您希望定位服务继续在后台运行,您必须在前台启动它,它将继续在后台运行。
如果您像我一样,请停止位置服务并使用计时器在后台重新启动它,它将无法正常工作。
有关更多详细信息,您可以观看 WWDC 2013 的前 8 分钟视频 307:https ://developer.apple.com/wwdc/videos/
2014 年 2 月更新: 经过几个月的尝试,我可以从使用 iOS 7 的设备连续获取位置。您可能会在这里看到完整的答案:Background Location Services not working in iOS 7
状态栏上的图标是否打开?我也有这种奇怪的行为。检查我的问题:startMonitoringSignificantLocationChanges 但一段时间后 didUpdateLocations 不再被调用
我发现重要的位置更改已开启,但只是停止并重新启动服务(对于重大更改)并没有触发新的位置。
您必须将类的pausesLocationUpdatesAutomatically
属性设置为false以禁止系统暂停位置更新。CLLocationManager