如何实施永久,定期,后台位置更新?

时间:2011-09-29 11:09:29

标签: android

该应用需要一个底层功能,可以获取位置并将其发送到服务器。这必须定期发生(大约每1-5分钟),但最重要的是它必须始终发生,永不停止,防止操作系统关闭进程以回收内存,以及应用程序本身未运行时。

我建议使用以下解决方案。我熟悉处理Android位置,这里的问题是确保它们继续,即使应用程序不在内存中,并通过内存回收持续存在。

  1. SERVICE。使用服务收集位置事件并处理它们。使用boot和screen-on广播来确保服务始终在运行(并且还可能提高服务优先级以防止内存回收)。

  2. 报警。我收集这些可以在内存短暂时关闭。我该如何防范呢?这似乎是一个丑陋的解决方案,因为无论如何位置都会按计划到达,因此似乎没有必要再使用其他基于时间的组件。

  3. 通过广播的位置。通过广播意图传送的位置意味着我可以在广播接收器中处理位置事件。这些位置警报会无限期地继续吗?除了设备关闭或应用程序关闭以外的任何其他设备会导致它们停止吗?

  4. 什么是最持久的方法?

1 个答案:

答案 0 :(得分:11)

  

这必须定期发生(大约每1-5分钟)但最重要的是它必须始终发生,永不停止,防止操作系统关闭进程以回收内存,以及应用程序本身未运行时。

这在各方面都不是严格可行的。

让我们一次拿一件:

  

必须定期(约每1-5分钟)

您可能无法获得地点,期限,更不用说每1-5分钟一次。用户可能已禁用所有位置提供程序。用户可能将设备置于飞行模式。用户可能位于连接较差的大型建筑物(阻挡GPS)中(使网络提供商不可靠)。

  

永不停止

用户可以通过“设置”或任务杀手中的“管理服务”屏幕随时清除您。如果他们这样做,特别是在Android 3.1+上,您的应用将永远不会再次运行,直到用户启动您的活动(例如,通过启动器)。当然,用户也可以卸载您的应用程序。

  

防止操作系统关闭进程以回收内存

你无法保证不会这样。你可以降低几率,但就是这样。


现在,让我们来看看你的各种解决方案:

  

使用服务收集位置事件并处理它们。

从你说出这个(和后续句子)的方式来看,你的意思是一个永恒的服务,一个旨在全天候运行的服务。根据定义,这意味着您的应用正在运行,这违反了您的一条规则。假设你放松了这个规则,这个解决方案大大增加了用户摆脱你的服务的几率,并增加了Android摆脱你的服务的几率。您可以使用startForeground()来最小化后者。

  

报警。我收集这些可以在内存不足时关闭。

不是我知道的。但是,如果用户将您清除,您的警报将被删除。

  

这似乎是一个丑陋的解决方案,因为地点无论如何都会按计划到达

不,他们不会。 requestLocationUpdates()上的时间参数并不意味着“地点无论如何都会按计划到达”。

  

通过广播意图传送的位置意味着我可以在广播接收器中处理位置事件。

不,你不能。您已指出您的部分工作是将此数据发送到服务器。您无法在主应用程序线程上可靠地执行此操作,因为它可能需要很长时间。 <{1}} getService(),指向PendingIntent会更可靠。

  

这些位置警报会无限期地继续吗?

没有。见下文。

  

除设备关闭或应用程序关闭以外的任何设备是否会导致它们停止?

用户可以摆脱您的应用程序(卸载,任务杀手,管理服务)。用户可以禁用位置提供程序。用户可以进入无法确定位置的区域。等

此外,该设备可能会入睡,AFAIK。系统可能会在您注册的更新请求期间保持IntentService。系统甚至可能在内部使用WakeLock来安排在您提供的时间段内唤醒自己,因此它不必持续保持设备唤醒。但是,您需要对此进行彻底测试。

  

什么是最持久的方法?

如果我的上一段中的问题由操作系统处理,那么您的第三个选项可能是最强大的。在AlarmManager中使用startForeground()并在退出IntentService()之前致电stopForeground() - 即使onHandleIntent()启动的短期服务可能因内存不足而被杀死令我惊讶的是。

话虽如此,您所期望的行为似乎可能比用户可能需要的电池寿命更长。请允许用户控制轮询周期,包括“从不轮询,我会手动更新内容”选项。