对GCM Token更新过程感到困惑

ran*_*ose 7 android google-cloud-messaging

试图实施谷歌的最新GCM服务.我已阅读GCM文档.我还下载并分析了谷歌的示例实施.从以上所述我了解以下内容:

  1. InstanceId服务提供API以生成gcm registration tokens您在应用服务器中发送和存储此生成的令牌.
  2. 这些令牌可以在一次从客户端的一阵子以及实例Id服务端所提到改变这里.要处理这个问题,你必须实现InstanceIDListenerService,InstanceID提供程序将调用 onTokenRefresh你编写逻辑的地方来获取新令牌并将其发送到服务器(Google的示例应用程序)
  3. 如果您的应用服务器发送较旧的注册ID,GCM服务器会发送您的设备,这里有一些称为canonical_id(如此处所述)(这是设备发送的最后一次registration_id).您必须使用此canonical_id替换服务器中的现有令牌.

现在,以下是我的问题:

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

roy*_*oyB 4

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

更好的解决方案是保存您已经成功注册令牌的首选项。RegistrationIntentService仅当您尚未注册时才开始。

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

然后当你启动你的应用程序时只需检查是否PREFIX_PREF_GCM_KEY为 true

如果您的应用程序未连接到 Play 商店(没有互联网或其他东西)时发生刷新,onTokenRefresh 会如何处理

我猜这是由系统来调用的refresh procedure。该文件指出:

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

它可以在您的应用程序处于睡眠状态时调用(与您收到通知时相同),但您应该测试它并查看它是否按预期工作。

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

canonical_id 到底是什么?

您可能错误地在服务器中为同一设备注册了多个注册 ID -例如 -onRefreshToken注册了一个令牌而没有删除旧的令牌。如果您将使用旧的发送消息registartaion_id,谷歌会让您知道您应该将其更改为新的 - canonical_id