Android C2DM:向同一设备和应用程序重复发送消息

9

我想知道是否有人在使用Google C2DM时遇到了这个问题?以下是我面临的情况:

  1. 用户安装应用并向C2DM服务器注册以获取注册密钥。
  2. 用户卸载应用。
  3. 用户重新安装应用(并向C2DM服务器注册以获取新的注册密钥)。

现在,我从我的服务器向用户手机发送消息,他们会收到重复的消息。

请问是否有人能解释一下这是否是预期行为或我该如何修复它? 谢谢。


1
你是说他们在短时间内接收到了两次相同的消息吗?这绝对不是期望的行为——当用户卸载时,他们的云密钥应该被标记为不再使用。很抱歉问一个愚蠢的问题——你确定你的服务器代码没有复制他们的云ID吗?你是否记录了所有c2dm服务器请求和Google返回的响应的日志? - Richard Green
5个回答

7

不确定这是否是最佳方法,但在android-c2dm组中有一个相关的主题,其中发帖人提供了一种技术:

我将注册ID发送到消息中,以便可以根据设备上存储的注册ID检查它。

如果不相同,则丢弃并通知服务注册ID不再使用

缺点是发送注册ID占用了已经受限制的消息大小中的一些空间。但在我的情况下非常完美,因为我的原始消息不超过几个字符。


厉害的技巧!看起来非常聪明。 - Matroska

4

这只会发生在重新安装应用程序后的第一条推送通知中。

当检测到已卸载的应用程序时,Google C2DM服务处于被动模式。

在未注销C2DM的情况下卸载您的应用程序后(第一次推送通知不会返回任何错误响应),但第二次推送通知将返回“无效注册”或“未注册”的错误代码,从而可以意识到应用程序已被卸载。

原因是C2DM服务器立即返回响应代码,然后才尝试推送客户端。 当客户端响应应用程序已被卸载时,它将从C2DM服务器中删除。 下一个推送尝试将立即返回错误代码。


但是,如果用户在卸载应用程序后立即安装并注册Reg_Id,那会发生什么呢?如果设备使用先前卸载之前有效的reg_id进行推送。消息会发送到设备还是会返回“无效注册”? - Erik
注册 ID 在每个设备、应用程序和已登录的 Google 用户中都是唯一的。我猜,在您所描述的情况下,应用程序将获得与先前安装相同的注册 ID,因此您应该没问题。 - Zamel

1

另一个解决方案可能是为设备提供唯一标识符,以便为您的服务器提供服务。在这种情况下,当设备在重新安装后尝试注册时,您只需更新该UUID的registrationID即可。


我正在我的应用程序架构中进行相同的实现。但是,如果C2DM服务返回注册无效,您也可以将其删除。 - Sir NIkolay Cesar The First

0

@Zamel 和 @johan 的回答都很好,需要结合起来。如果您将两种解决方案结合起来,那么您将最小化服务器的数据库。

因此,最好的解决方案是:

  1. 在向服务器发送推送令牌时发送设备ID

  2. 当为现有设备ID发送推送令牌时更新推送令牌

  3. 如果推送通知返回“无效注册”或“未注册”错误代码,则在服务器的数据库中使推送令牌无效

当推送令牌被识别为“无效注册”或“未注册”时,您可以使其无效(将其标记为空),删除数据库中的行或实现过期功能。这取决于您的需求。


0

是的,我也遇到了同样的问题,我认为这是Android C2DM实现中的一个大疏忽。在iOS中,处理得更好,因为一个应用程序只能接收一个设备令牌(相当于c2dm注册ID)的通知。

我使用的解决方法是将注册ID的最后10个字符作为c2dm负载的一部分发送,然后在我的onMessage方法中进行以下检查:

    if (!regId.endsWith(bundle.getString("regsuffix"))) return null;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接