要求 - 我需要大约每15分钟获取用户的位置坐标并将其发布到服务器。有必要大致以这些间隔发布数据。
实施 - 我已经制作了同步适配器,而不是使用AlarmManager,因为它节省了电量。我已将ContentResolver.addPeriodicSync()
设置为每15分钟大致同步一次我的应用,获取当前位置并发布到服务器。
问题 - 如果没有互联网连接,我希望每15分钟继续访问用户的位置并将其保存在本地sqlite数据库中。当互联网下次再次回来时,我会一次性发布所有已保存的位置,以便服务器数据保持一致,然后同步将恢复正常。
主要问题是当没有互联网时,同步停止,我停止在我的应用程序中定期进行同步回调,我无法在本地数据库中保存数据。所以我想要的是,即使没有互联网,我也会定期收到回叫,直到互联网回来并再次启动自动同步。同步适配器可以这样做吗?
一个解决方案我能想到的是,当互联网停止时我会收到广播,此时我开始使用AlarmManager每15分钟启动一次服务并获取位置并保存到本地数据库。当互联网重新启动时,我停止使用AlarmManager并返回自动同步。
解决方案2 - 由David Medenjak提供。由于AlarmManager的setInexactRepeating()
行为试图通过为不同的应用程序安排警报来模仿同步适配器的行为以减少CPU唤醒的次数,因此它也很有效。它也导致更简单的实现。这比以前的解决方案比较利弊更好吗?
还有更好的方法来实现这个目标吗?
答案 0 :(得分:2)
你混合了两件事:
如果您开始混合具有彼此强烈依赖的服务和同步适配器的那些,则必须检查哪些已运行以及应运行哪些状态。你最终可能得到你想要的东西(每15分钟同步一次,如果用户离线则只缓存它)但是很难测试和维护。
始终使用每15分钟运行一次的服务来存储当前用户位置。
定期同步对服务器的所有更新。这可能也是每15分钟发生一次,但你不应该依赖于此。
通过让一个部件只存储位置而另一个部件只是同步数据,您将更容易处理事情。而且您也不必担心互联网连接或同步间隔(因为不能保证同步适配器在确切的时间运行)。
关于电池续航时间 (评论)
SyncAdapter
是否使用gps并立即发布或者服务暂时保留它直到适配器同步它应该没有什么大的区别。一旦任务必须每隔x分钟运行一次,设备就必须醒来。
如果以与服务相比较慢的速度运行同步,可能会有轻微的改进,因为单独的gps 可能不需要任何互联网连接。
答案 1 :(得分:0)
IntentService
- 每15分钟运行一次(使用AlarmManager
)并将用户位置保存在数据库中并将其标记为未发送。
SyncAdapter
- 每15分钟运行一次,并将所有未发送的位置发送到服务器。成功时将位置标记为已发送。 Android将确保它仅在有互联网连接时运行。
编辑:
关键点在于分离两个子任务(也由@David Medenjak建议):
1)获取位置更新并将其存储在数据库中
2)当有网络连接时,将位置更新发送到服务器。
FusedLocationProvider
有方法
requestLocationUpdates (GoogleApiClient client, LocationRequest request, PendingIntent callbackIntent)
适用于您的应用何时在后台。 Link
此方法更适用于后台用例 用于接收位置更新,即使应用程序已被杀死 系统。
您可以使用LocationRequest
来设置优先级,间隔,功耗。 Link
当您收到待处理的意图时,您可以在数据库中插入该位置并使用同步适配器请求同步。