7

我有一个 Android 应用程序,它具有聊天客户端作为其功能之一。聊天客户端使用基于 Android 的Smack库的 XMPP,并在后台运行Openfire作为 XMPP 服务器。连接是使用BOSH建立的。整个 XMPP 连接处理是作为一项服务实现的,即使应用程序的活动不在前台,也可以在后台运行和侦听传入消息。到目前为止,一切正常。

唯一的问题似乎是睡眠模式。在模拟器中(当设置为“保持清醒”时)或使用手机时,XMPP 连接保持不变,应用程序可以发送和接收消息。但是,一旦手机进入睡眠模式,XMPP 连接就会中断——我可以在 Openfire 服务器的管理控制台中看到用户离线。直观地说,我想一直接收消息,例如 WhatsApp。

当然,我在网上搜索过,包括 Stackoverflow,但我无法得到明确的答案。通常,用例似乎是必须定期执行一项任务,例如每小时一次。但这似乎不适用于聊天客户端。因为我认为这是一个常见的用例——毕竟,有这么多聊天应用程序或具有聊天功能的应用程序——这些是我的问题:

  • 如何更改/扩展可以在手机睡眠时接收聊天消息的应用程序?

  • 我偶然发现WakeLock。这是要走的路还是这些不适合我的用例?

  • 自 Lollipop 以来,还有JobSchedulerAPI 本身使用WakeLock. 好点?

  • 例如,WhatsApp 如何处理这种情况?

附带说明:我在使用模拟器进行调试时遇到了睡眠模式的问题。当我在模拟器中关闭“保持清醒”时,屏幕在 1+ 分钟后变黑并且 XMPP 连接中断。但是我不知何故不知道一旦模拟器变黑如何唤醒/重新打开模拟器。Android Studio 实际上在某些时候告诉我设备或其他东西不见了,我必须再次重新启动模拟器。

4

2 回答 2

5

解决此问题的确切方法是使用推送通知。

XMPP 连接的自然行为是在指定的空闲时间间隔后断开连接,即当设备进入睡眠状态时。

以 WhatsApp 为例,它也使用相同的 XMPP 并维护一个服务器,该服务器充当所交换消息的包装类。该服务器检查消息状态是否已送达。如果未传递,它会发送一个推送通知,现在在推送服务中的设备端收到消息时,它会检查连接是否处于活动状态以及是否经过身份验证。

如果未通过身份验证,它将重新建立连接。通过这种方式,大多数聊天应用程序都会管理此超时异常。

希望这可以帮助 :)

于 2017-01-24T03:23:46.867 回答
3

你不需要推送通知,你不需要WakeLocks。而是简单地

  • 将您的应用从打盹模式列入白名单
  • 使用粘性 ( START_STICKY) 后台服务
  • 使用 SmackServerPingWithAlarmManager
  • CONNECTIVY_CHANGEDAndroid 发送的意图采取行动,在这种情况下使用XMPPTCPConnection's instantShutdown()
于 2017-01-25T11:46:00.427 回答