Android 如何实现永久、定期的后台位置更新?

Android 如何实现永久、定期的后台位置更新?,android,Android,该应用程序需要一个底层功能,可以拾取位置并将其发送到服务器。这必须定期发生(大约每1-5分钟一次),但最重要的是,它必须一直发生,从不停止,防止操作系统关闭进程以回收内存,并且在应用程序本身未运行时发生 有人向我提出了以下解决办法。我熟悉处理Android位置,这里的问题是确保它们继续运行,即使应用程序不在内存中,并通过内存回收保持 服务。使用服务收集并处理位置事件。在广播中使用引导和屏幕以确保服务始终运行(并可能增加服务优先级以防止内存回收) 警报。我想当内存不足时可以关闭这些。我该如何防范这

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

有人向我提出了以下解决办法。我熟悉处理Android位置,这里的问题是确保它们继续运行,即使应用程序不在内存中,并通过内存回收保持

  • 服务。使用服务收集并处理位置事件。在广播中使用引导和屏幕以确保服务始终运行(并可能增加服务优先级以防止内存回收)

  • 警报。我想当内存不足时可以关闭这些。我该如何防范这种情况?这似乎是一个丑陋的解决方案,因为位置无论如何都会按计划到达,因此似乎没有必要再使用另一个基于时间的组件

  • 地点通过广播。通过广播目的交付的位置意味着我可以在广播接收器中处理位置事件。这些位置警报是否会无限期持续?除了设备关闭或应用程序关闭它们之外,还会有其他原因导致它们停止吗

  • 最持久的方法是什么

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

    这在很多方面都是不可能的

    让我们一次拿一块:

    这必须定期进行(大约每1-5分钟一次)

    您可能无法获取位置、时段,更不用说每1-5分钟一次。用户可能已禁用所有位置提供程序。用户可能使设备处于飞行模式。用户可能在连接不良(使网络提供商不可靠)的大型建筑物中(阻止GPS)

    永不停止

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

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

    你不能对此作出保证。你可以降低几率,但仅此而已


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

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

    从你表达这一点(以及随后的句子)的方式来看,你指的是一个永久性的服务,一个设计为全天候运行的服务。根据定义,这意味着您的应用程序正在运行,这违反了您的规则之一。假设你放松这条规则,这个解决方案会大大增加用户放弃你的服务的几率,也会增加Android放弃你的服务的几率。您可以使用
    startForeground()
    将后者最小化

    警报。我想当内存不足时可以关闭这些

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

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

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

    通过广播目的交付的位置意味着我可以在广播接收器中处理位置事件

    不,你不能。您已经指出,您的部分工作将是将此数据发送到服务器。您无法在主应用程序线程上可靠地执行此操作,因为这可能需要太长时间。一个
    getService()
    pendingent
    ,指向一个
    IntentService
    会更可靠

    这些位置警报是否会无限期持续

    不,见下文

    除了设备关闭或应用程序关闭它们之外,还会有其他原因导致它们停止吗

    用户可以删除你的应用程序(卸载、任务杀手、管理服务)。用户可以禁用位置提供程序。用户可能会进入无法确定位置的区域。等等

    另外,设备可能会睡着。在您注册的更新请求期间,系统可能会保持
    唤醒锁定。系统甚至可能在内部使用
    AlarmManager
    来安排在您提供的时间段内唤醒自己,因此不必让设备持续处于唤醒状态。但是,您需要彻底测试这一点

    最持久的方法是什么

    如果我上一段中的问题是由操作系统处理的,那么您的第三个选项可能是最健壮的。在您的
    IntentService()
    中使用
    startForeground()
    ,并在退出
    onHandleIntent()
    之前调用
    stopForeground()
    ——即使是由
    AlarmManager
    启动的短期服务也可能由于内存不足而停止,这让我感到非常惊讶

    这就是说,您想要的行为似乎可能会消耗比用户可能想要的更多的电池寿命。请允许用户控制轮询周期,包括“从不轮询,我将手动更新内容”选项