【发布时间】:2016-06-01 15:06:41
【问题描述】:
我正在尝试制作一个应用程序来一直跟踪用户 GPS,这个应用程序是一种汽车 GPS 跟踪器,可以一直获取驾驶员的位置并将其发送到服务器。
我尝试将“位置更新”添加到“后台模式”,但应用程序会在进入后台 10 分钟后自动挂起。
有没有办法让这个应用程序一直运行并获取 GPS 位置?
【问题讨论】:
标签: ios gps core-location
我正在尝试制作一个应用程序来一直跟踪用户 GPS,这个应用程序是一种汽车 GPS 跟踪器,可以一直获取驾驶员的位置并将其发送到服务器。
我尝试将“位置更新”添加到“后台模式”,但应用程序会在进入后台 10 分钟后自动挂起。
有没有办法让这个应用程序一直运行并获取 GPS 位置?
【问题讨论】:
标签: ios gps core-location
您有两种选择:
1) 常规位置跟踪。
这种类型的跟踪适用于 kCLAuthorizationStatusAuthorizedWhenInUse 和 kCLAuthorizationStatusAuthorizedAlways 授权。当CLLocationManager 开始跟踪位置时,它将在委托方法locationManager:didUpdateLocations: 中接收位置更新。应用程序可以进入挂起状态,但是当位置管理器收到新位置时,应用程序会进入后台状态并在委托方法中处理新位置。如何设置位置管理器:
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
// Setup location tracker accuracy
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
// Distance filter
self.locationManager.distanceFilter = 50.f;
// Assign location tracker delegate
self.locationManager.delegate = self;
// This setup pauses location manager if location wasn't changed
[self.locationManager setPausesLocationUpdatesAutomatically:YES];
// For iOS9 we have to call this method if we want to receive location updates in background mode
if([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]){
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
[self.locationManager startUpdatingLocation];
}
2) 标识位置更改跟踪。
这种类型的跟踪仅适用于kCLAuthorizationStatusAuthorizedAlways 授权。它仅每 500 米接收新位置,因此距离过滤器和期望精度在这里不起作用。应用程序可以进入挂起状态,甚至可以被系统终止,但是当位置更新时,应用程序进入后台状态并在委托方法locationManager:didUpdateLocations:中接收位置。
如果应用程序被系统终止,它将在后台重新启动在didFinishLaunchingWithOptions 应用程序委托方法中使用UIApplicationLaunchOptionsLocationKey 键在启动选项中。如何在跟踪中设置此类型:
- (void)viewDidLoad {
[super viewDidLoad];
self.locationManager = [[CLLocationManager alloc] init];
// Assign location tracker delegate
self.locationManager.delegate = self;
// For iOS9 we have to call this method if we want to receive location updates in background mode
if([self.locationManager respondsToSelector:@selector(allowsBackgroundLocationUpdates)]){
[self.locationManager setAllowsBackgroundLocationUpdates:YES];
}
[self.locationManager startMonitoringSignificantLocationChanges];
}
您应该注意到,这两种方法都不能保证您的应用程序不会进入挂起状态。
此外,如果应用程序被用户终止(例如从应用程序切换器通过滑动),后台的位置跟踪将不起作用。
UPDATE(对应cmets)
这是适用于我的代码示例:
For Regular tracking。运行示例,提供对用户位置的访问,点击 Start 按钮开始位置更新。要在模拟器中测试位置,请在模拟器菜单 Debug > Location > Freeway Drive 中选择。现在您可以通过主页按钮 (Command+Shift+H) 将应用程序推到后台。离开模拟器超过 10 分钟,所有这段时间应用程序都会收到位置。当您返回应用程序时,您会在地图上看到红色图钉。
For Significant changes。以与上一个示例相同的方式运行应用程序并进行测试。
监控 重大变更只能通过[self.locationManager startMonitoringSignificantLocationChanges];方法启动
更新(iOS 11)
iOS 11 中位置跟踪的变化
iOS 11 还对现有 API 进行了一些重大更改。受影响的领域之一是位置跟踪。 如果您的应用只在应用处于前台时使用位置,就像大多数应用一样,您可能根本不需要更改任何内容;但是,如果它是全天持续跟踪用户位置的应用之一,那么您可能应该在今年夏天预订一些时间来对跟踪和测试可能的使用场景的方式进行一些更改。
点击此链接:https://mackuba.eu/2017/07/13/changes-to-location-tracking-in-ios-11/
【讨论】:
回复解决方案中的评论 1(我无法在任何地方发表评论):您似乎没有解决问题,因为您的应用程序被暂停并且 10 分钟后不再更新位置。
我遇到了同样的问题:我将setAllowsBackgroundLocationUpdates 设置为YES,并且我的NSLocationAlwaysUsageDescription 键在我的Info.plist 中,但我的应用程序也曾经在10 分钟后停止跟踪位置。
我通过将NSLocationAlwaysUsageDescription 和NSLocationWhenInUseUsageDescription 添加到Info.plist 文件来解决它,所以它看起来像这样:
<key>NSLocationAlwaysUsageDescription</key>
<string>This app needs to use your location</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs to use your location</string>
【讨论】:
设置它。它需要电池供电,但您的应用程序在后台运行。OS 不会暂停您的应用程序
[self.locationManager setPausesLocationUpdatesAutomatically:NO];
【讨论】:
我相信这对作者很有用,因为这个问题是在 2016 年 2 月提出的,我在 2019 年 6 月给出了答案。这个答案可能对其他用户有用。
最近,我正在处理相同的要求。经过2-3周的努力,我做到了。对于其他用户,我为它创建了一个帮助类。可以在 GitHub 中找到。
请使用HSLocationManager 满足您的要求。我在我的一个项目中达到了同样的要求
位置管理器,允许每次获取后台位置更新 n 秒,具有所需的位置精度。
优势:
如果位置管理器当前处于 正在运行。
在需要时定期更新位置(范围在 2 - 170 秒(受允许的最大后台任务时间限制))
可自定义定位精度和时间段。
低内存消耗(单例类)
【讨论】: