对GCM Token更新过程感到困惑

时间:2015-08-23 08:57:20

标签: android google-cloud-messaging

尝试实施谷歌最新的GCM服务。我看过GCM documentation。我还下载了&分析google's sample implementation。从以上所述我了解以下内容:

  1. InstanceId服务提供API以生成gcm registration tokens您发送&将此生成的令牌存储在您的应用服务器中。
  2. 这些令牌可以偶尔从客户端和instanceId服务端更改一次,如here所述。要处理此问题,您必须实现InstanceIDListenerService,InstanceID提供程序将调用onTokenRefresh,您只需编写逻辑来获取新令牌并将其发送到服务器(Google's sample app
  3. 如果您的应用服务器发送较旧的注册ID,GCM服务器会向您的设备发送名为canonical_idas mentioned here)(这是设备发送的最后一次registration_id)。您必须使用此canonical_id替换服务器中的现有令牌。
  4. 现在,以下是我的问题:

      如果未卸载应用程序,则
    1. InstanceId.getToken似乎返回相同的令牌,如果令牌未更改,则返回相当快。那么,每次启动应用程序时,我都可以调用RegistrationIntentService吗?这样我就可以保证一直使用最新的令牌。
    2. 如果您的应用未连接到Play商店(没有互联网或其他内容),onTokenRefresh如果刷新了怎么办? InstanceId提供商会重试吗?这是在某处记录的吗?如果同时发送推送通知会发生什么?
    3. canonical_id究竟是什么?它是为设备生成的最新令牌(由InstanceID.getToken在客户端或InstanceId提供商端发起)?如果canonical_id确实是最新的gcm令牌,那么onTokenRefresh实施的需求是什么,因为如果您发现提供了canonical_id,您仍然可以分析推送通知数据并更新您的应用服务器? / LI>

1 个答案:

答案 0 :(得分:4)

  

每次启动应用程序时都可以调用RegistrationIntentService吗?

更好的解决方案是优先保存您已设法注册令牌。只有在您尚未注册时才开始RegistrationIntentService

String token = InstanceID.getToken(...);
//send to server
getSharedPreferences(context).edit().putBoolean(PREFIX_PREF_GCM_KEY, true).apply();

然后当您启动应用时,只需检查PREFIX_PREF_GCM_KEY是否为真

  

当您的应用未连接到Play商店(没有互联网或其他东西)时,如何刷新onTokenRefresh

我猜这是由系统来调用refresh procedure。文件说明:

  

系统确定需要刷新令牌时调用。应用程序应调用getToken()并将令牌发送到所有应用程序服务器。   这不会被频繁调用,需要进行键旋转和处理特殊情况。   系统将限制所有设备上的刷新事件,以避免使用令牌更新使应用程序服务器过载。

可以在您的应用程序处于睡眠状态时调用(与收到通知时相同),但您应该对其进行测试,并确保其按预期工作。

我还认为您可以假设虽然没有互联网连接,但System不会调用onRefreshToken,原因很简单,因为它无法接收更新通知...但一如既往,您应该自己测试一下,看看更新过程是否有效以及在哪些条件下。

  

canonical_id究竟是什么?

您可能错误地在您的服务器中为同一设备注册了多个注册ID - 例如 - onRefreshToken - 注册了一个令牌而不删除旧令牌。 如果您使用旧registartaion_id发送邮件,Google会通知您应将其更改为新邮件 - canonical_id