【问题标题】:iOS Location Manager stops after phone is locked for ~10 minutesiOS 位置管理器在手机锁定约 10 分钟后停止
【发布时间】:2015-09-18 01:20:15
【问题描述】:

我正在尝试在我的应用处于后台时获取位置。当我使用我的应用程序时,一切都很好。我也可以切换到任何其他应用程序(甚至是主屏幕)并且位置仍然可以进入。如果我正在使用我的手机但我的应用程序在后台,只要我的手机处于活动状态,位置更新似乎就可以了(未锁定)。

但是,如果我锁定手机并在大约 10 分钟后回来,状态栏中的位置图标和我的应用不再获取位置更新。

我检查了应用程序崩溃,但没有崩溃报告。我的应用仍然出现在应用列表中,所以我认为它没有崩溃。

如果我请求“始终”许可,GPS 是否应该永远保持开启状态。还是手机休眠一段时间后操作系统会关闭它?

这是我的 plist 中的条目:

<key>NSLocationAlwaysUsageDescription</key>
<string></string>
<key>NSLocationWhenInUseUsageDescription</key>
<string></string>

下面是后台定位服务的截图:

这是我的自定义类,即位置管理器委托:

@interface LocationDelegate ()
    @property (nonatomic, strong) CLLocationManager *locationManager;
@end

@implementation LocationDelegate

+ (instancetype) singleton {
    static LocationDelegate *delegate = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        delegate = [[self alloc] init];
    });
    return delegate;
}

- (id) init {
    if (self = [super init]) {
        // for now filter and accuracy are based on the same preference
        _locationManager = [[CLLocationManager alloc] init];
        _locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
        _locationManager.delegate = self;

        // Check for iOS 8
        if ([_locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
            [_locationManager requestAlwaysAuthorization];
        }

    return self;
}

注意它是一个单例。这有关系吗?在我的应用程序在后台运行一段时间或暂停后,此类是否会被清理?从我读过的内容来看,我不认为像这样的单例会被清理,因为它们是强引用,所以我认为这不是问题......但我真的不知道为什么我在一定数量后停止获取位置时间。

编辑:

我的位置管理器似乎在一段时间后暂停位置更新。最大的问题是我没有接到简历电话。

我将activityType设置为默认值

CLActivityTypeOther

我可以尝试其他活动类型,看看是否会有所作为。但是,我依靠我的应用程序来进行步行和驾驶。

我想我遇到了同样的问题:

iPhone GPS in background never resumes after pause

【问题讨论】:

  • 嗨@lostintranslation,我有同样的问题。如果你有,请给我答案。

标签: ios objective-c iphone cllocationmanager


【解决方案1】:

是的,只要您在 BackgroundModes 中允许它,它就应该保持打开状态,请求 requestAlwaysAuthorization 并添加 NSLocationAlwaysUsageDescription。但是,NSLocationAlwaysUsageDescription 必须有描述,您的 XML 看起来好像没有。显然,你还需要调用 startUpdatingLocation。

如果您认为您的单例可能是问题的一部分,请尝试将代码移至 appDelegate。

【讨论】:

  • NSLocationAlwaysUsageDescription 可以是空字符串。我肯定会更多地研究单例。
  • 我将它与我的 (Swift) 代码进行了比较,我认为我没有做任何不同的事情,除了我没有单例并且对于 iOS9 我还添加了locationManager.allowsBackgroundLocationUpdates = true。该应用程序会正确进行后台更新。
【解决方案2】:

不,它不一定会继续在后台运行。默认情况下,pausesLocationUpdatesAutomatically 设置为 YES,这与 activityType(如果设置)一起帮助操作系统确定何时可以安全地暂停位置更新以节省电量。如果操作系统暂停了您的更新,您可以实现locationManagerDidPauseLocationUpdates: 委托来记录。

另外,需要明确的是,设置 requestAlwaysAuthorization 并不意味着 locationManager 会继续运行,它只是意味着您的应用可以从前台或后台或挂起模式启动 locationManager。

【讨论】:

  • pausesLocationUpdatesAutomatically 设置为 YES 应该没问题。只要我再次开始移动,位置管理器就会开始备份“取消暂停”,这不会发生。我会检查它是否由于某种原因正在暂停而不是重新启动。此外,当您说“并不意味着 locationManager 将继续运行”时,保持位置管理器运行的正确方法是什么?如果您需要我发布更多代码,请告诉我。
  • 是的,如果您再次开始移动,locationManager 应该再次开始更新。当它重新启动时,它应该调用locationManagerDidResumeLocationUpdates: 但是,根据您的距离过滤器和精度设置,它可能需要一些移动才能重新启动。您还应该查看在 locationManager 上设置 activityType 以帮助操作系统知道何时暂停更新。在您的情况下,您可能希望将其设置为 CLActivityTypeAutomotiveNavigation
  • 我的应用使用汽车和行人的位置数据。当用户走路时,将 activityType 设置为 CLActivityTypeAutomotiveNavigation 会导致问题吗?目前它被设置为默认的“CLActivityTypeOther”。看起来我的位置经理在重大变动后没有恢复
  • 由于您将应用程序用于步行和自动驾驶,因此您应该让用户能够设置他们使用它的目的,例如地图应用程序。然后,您可以在 CLActivityTypeFitnessCLActivityTypeAutomotiveNavigation 之间切换类型
  • 不幸的是,无论距离过滤器和活动类型如何,iOS 都不会在暂停后恢复。与我链接的其他 SO 帖子中概述的问题相同。现在回答它现在允许暂停。
【解决方案3】:

暂停后重新启动与不让它暂停具有相同的效果。是的,这是一个电池问题,但如果我希望它在用户再次开始移动时运行,这是我唯一的选择。

【讨论】:

    猜你喜欢
    • 2017-03-26
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 2018-06-03
    • 1970-01-01
    相关资源
    最近更新 更多