问题 iOS GPS跟踪应用程序一直运行


我正在尝试制作一个应用程序来跟踪用户GPS,这个应用程序是一种车载GPS跟踪器,以获取驱动程序的位置,并将其发送到服务器。

我试图将“位置更新”添加到“后台模式”,但应用程序将在进入后台10分钟后自动暂停。

有没有办法让这个应用程序一直运行并获得GPS位置?

谢谢。


10842
2018-02-19 21:37


起源



答案:


你有两个选择:

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:
如果应用程序被系统终止,它将在后台重新启动 UIApplicationLaunchOptionsLocationKey 关键的启动选项 didFinishLaunchingWithOptions app委托方法。如何在跟踪时设置此类型:

- (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 (对应评论)

这是我的代码示例,对我有用:
对于常规跟踪。运行示例,提供对用户位置的访问权限,点击 开始 按钮开始位置更新。要在模拟器中测试位置,请在模拟器菜单Debug> Location> Freeway Drive中选择。现在,您可以通过主页按钮(Command + Shift + H)将应用程序推送到后台。离开模拟器超过10分钟,所有这些时间应用程序将收到位置。当您返回应用程序时,您将在地图上看到红色别针。
对于重大变化。以与上一个示例相同的方式运行应用程序并进行测试。
监控重要更改只能通过方法启动 [self.locationManager startMonitoringSignificantLocationChanges];

UPDATE (iOS 11)

iOS 11中位置跟踪的更改

iOS 11还对现有API进行了一些重大更改。其中一个受影响的区域是位置跟踪。 如果您的应用仅在应用位于前台时使用位置,就像大多数应用程序一样,您可能根本不需要改变任何东西;但是,如果它是那些在一天中持续跟踪用户位置的应用程序之一,那么您应该在今年夏天预订一些时间,以便对如何跟踪和测试可能的使用方案进行一些更改。

点击此链接: https://mackuba.eu/2017/07/13/changes-to-location-tracking-in-ios-11/


10
2018-02-20 00:41



谢谢你的答案,对于选项1,你说当收到新的位置时,状态从暂停到后台,我已经测试了几天,这个案子从来没有发生在我身上,应用程序再次恢复生机手动运行应用程序,然后在10分钟后暂停,为什么??? - TMMDev
对于选项2,有没有办法让startMonitoringSignificantLocationChanges以某种方式运行[self.locationManager startUpdatingLocation]?这将使它至少每500米运行一次 - TMMDev
更新了您的评论的答案。我没有看到你的代码,所以我在这里为选项1和2提供了代码示例的链接。 - shpasta
我已经将你的帖子标记为答案,因为你写的正是我正在寻找的“你应该注意到这两种方法都不能保证你的应用程序不会进入暂停状态” - TMMDev


答案:


你有两个选择:

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:
如果应用程序被系统终止,它将在后台重新启动 UIApplicationLaunchOptionsLocationKey 关键的启动选项 didFinishLaunchingWithOptions app委托方法。如何在跟踪时设置此类型:

- (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 (对应评论)

这是我的代码示例,对我有用:
对于常规跟踪。运行示例,提供对用户位置的访问权限,点击 开始 按钮开始位置更新。要在模拟器中测试位置,请在模拟器菜单Debug> Location> Freeway Drive中选择。现在,您可以通过主页按钮(Command + Shift + H)将应用程序推送到后台。离开模拟器超过10分钟,所有这些时间应用程序将收到位置。当您返回应用程序时,您将在地图上看到红色别针。
对于重大变化。以与上一个示例相同的方式运行应用程序并进行测试。
监控重要更改只能通过方法启动 [self.locationManager startMonitoringSignificantLocationChanges];

UPDATE (iOS 11)

iOS 11中位置跟踪的更改

iOS 11还对现有API进行了一些重大更改。其中一个受影响的区域是位置跟踪。 如果您的应用仅在应用位于前台时使用位置,就像大多数应用程序一样,您可能根本不需要改变任何东西;但是,如果它是那些在一天中持续跟踪用户位置的应用程序之一,那么您应该在今年夏天预订一些时间,以便对如何跟踪和测试可能的使用方案进行一些更改。

点击此链接: https://mackuba.eu/2017/07/13/changes-to-location-tracking-in-ios-11/


10
2018-02-20 00:41



谢谢你的答案,对于选项1,你说当收到新的位置时,状态从暂停到后台,我已经测试了几天,这个案子从来没有发生在我身上,应用程序再次恢复生机手动运行应用程序,然后在10分钟后暂停,为什么??? - TMMDev
对于选项2,有没有办法让startMonitoringSignificantLocationChanges以某种方式运行[self.locationManager startUpdatingLocation]?这将使它至少每500米运行一次 - TMMDev
更新了您的评论的答案。我没有看到你的代码,所以我在这里为选项1和2提供了代码示例的链接。 - shpasta
我已经将你的帖子标记为答案,因为你写的正是我正在寻找的“你应该注意到这两种方法都不能保证你的应用程序不会进入暂停状态” - TMMDev


回答解决方案中的评论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>

1
2018-05-26 22:09





设置它。获取电池电量,但您的应用程序在Background.OS运行不会暂停您的应用程序

[self.locationManager setPausesLocationUpdatesAutomatically:NO];

1
2017-11-11 13:39