【问题标题】:CoreMotion updates in background state后台状态下的 CoreMotion 更新
【发布时间】:2013-12-03 16:24:31
【问题描述】:

借助最新 iOS 设备中的 M7 芯片,用户可以使用 CMMotionActivityManager 在用户从静止状态变为跑步、步行等时以编程方式获得通知。当它检测到用户没有通过 M7 移动时,Stava 和 Runkeeper 都使用它来auto-pause GPS polling(关闭 GPS 天线),然后在他们再次移动时重新启用 GPS 更新。它能够在应用程序处于后台状态时执行此操作,这是这里的关键。

我在复制此功能时遇到的问题是,如果我在我的应用程序处于后台时关闭 GPS 更新,我将停止接收活动更新,并且无法再检测到用户何时再次通过 M7 移动以打开 GPS重新开始。

如果我让 GPS 一直运行,我将在应用程序处于后台的整个时间里继续从 Core Motion 获取运动更新。

我假设他们没有玩白噪声或其他廉价技巧来保持活跃。他们是怎么做到的?

【问题讨论】:

  • this answer。将desiredAccuracy 设置为 3 公里会关闭 GPS,但应用程序会继续运行。
  • @progrmr 试了一下 - GPS 指示器在 3k 处保持活动状态。 Runkeeper 和 Strava 都会在静止时关闭 GPS 指示器(这几乎意味着调用 stopUpdatingLocation)。他的方法似乎只依赖于 3k = cell-tower 轮询。但是 3k 并不能保证只有小区,而且在弱小区位置,这仍然是我想避免的消耗。
  • 这有点棘手,但我想象一个三元组解决方案。如果您使用 beginBackgroundTaskWithName:expirationHandler 和 backgroundTimeRemaining 检查来自 CoreMotion 的 UIAccelerometer 数据,并在出现前向运动的事件时重新激活 GPS,或者在 backgroundTimeRemaining 或 significationLocationChange 终止时重新激活 GPS 会怎样?
  • @Parrots..@Jan 你找到什么了吗?我正在寻找同样的东西。

标签: ios core-location core-motion apple-m7


【解决方案1】:

我注意到当你关闭 GPS 时,应用程序不会在 iOS 7 的后台执行任何代码,应用程序看起来处于非活动状态。移动到后台时使用startMonitoringSignificantLocationChanges 并从您的位置经理那里获得更新会更好。意味着同时在用户状态更改时使用服务startUpdatingLocation,在后台使用startMonitoringSignificantLocationChanges

所以当用户打开 GPS 时,当您使用 startMonitoringSignificantLocationChanges 您的应用程序将收到

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations

最好在后台检查一下 CoreMotion 框架有什么问题。并尝试重新启动它。 因为没有 M7 芯片设备,我可以在这种情况下读取加速度计读数。

【讨论】:

    【解决方案2】:

    首先,检查您是否设置了应用的后台行为。

    转到目标 - 功能部分并检查后台模式以获取位置更新。

    【讨论】:

    • 谢谢,但这无济于事。后台启用,问题是如果我在 M7 报告静止时关闭 GPS 轮询,应用程序完全后台并且无法恢复。
    【解决方案3】:

    RunKeeper 实际上确实使用了音频技巧来保持清醒。如果您打开应用程序包并检查其 Info.plist,您将看到它注册了背景音频模式。这就是他们如何定期发送有关您的距离、速度和步速的音频通知。这也是它们在您跑步期间保持清醒同时最大程度地减少电池消耗的方式。

    如果您注意到在使用 RunKeeper 时位置服务图标(状态栏中的三角形)完全消失了,那么他们肯定没有使用任何类型的位置跟踪来完成后台执行。即使激活地理围栏和重要的位置变化监控也会导致位置服务图标出现。

    他们也没有使用 M7 来保持清醒,因为它不是那样工作的。来自 M7 相关 CoreMotion API 的更新不会将您的应用从睡眠中唤醒。当他们的应用确实醒来时,他们将能够查询 Motion Activity 和 Step 历史记录,并可能尝试计算一些东西,但我怀疑它会那么准确。

    最后您应该注意,在 iPhone 5s 和 M7 芯片发布之前,iOS 6 中引入了 Auto-pause API。它们是正交概念。

    【讨论】:

    • RunKeeper 中存在背景音频声明并不是音频保活技巧的证明。他们在运行时播放语音​​以通知您您的进度,通常是在应用程序在后台运行时。这将需要标志。
    • 我主要考虑的是 M7 之前的 Runkeeper 计步器。他们唯一的音频功能是每 1000 步发出一次哔声。这是间接证据,只是我的一个理论,但这正是它在技术上的运作方式,并且仍然得到了 Apple 的批准。
    • 我在某处读到过,如果我们使用 VOIP 只是为了保持活力,那么应用就会被拒绝。有什么合法的方法可以做到这一点吗?
    • 敲开应用程序证明此信息不再准确。
    • 为什么是@ChuckKelly?看起来与此答案相同。
    【解决方案4】:

    您是否考虑过尝试

    application:performFetchWithCompletionHandler: 
    

    在应用程序委托中?您无法控制调用的频率,但取决于应用程序,它可以每约 15 分钟调用一次。然后,您可以从那里启动 CMMotionActivityManager 来查询 M7 结果。

    尚不完全清楚您要复制什么功能,但 M7 芯片会记录所有活动,无论您的应用是否正在运行。因此,您可以简单地在后台查询并更新步数总计或活动类型总计。

    【讨论】:

      【解决方案5】:

      如果您的位置管理器在主动模式下工作,要启用后台模式,您需要执行以下三个步骤:

      1. 检查[目标/功能/后台模式/位置更新]是否已启用。
      2. [locationManager requestAlwaysAuthorization];
      3. locationManager.allowsBackgroundLocationUpdates = YES;

      【讨论】:

      • 这已被否决,但在我的情况下,我只是忘记了有一个 allowBackgroundLocationUpdates 位置管理器,所以它解决了我在后台获取 CoreMotion 更新的问题......
      • 我同意肯德尔,所以我赞成这个答案
      猜你喜欢
      • 2018-09-21
      • 2022-10-19
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-04
      • 2016-10-02
      相关资源
      最近更新 更多