如果应用程序从未更新且InstanceID提供程序从未启动刷新,GCM注册令牌是否保持不变?

3
我正在我的应用程序中使用Google的GCM服务。我尝试了示例代码,并且它对我很好用。但是有一件事情让我困惑,那就是关于注册令牌。
RegistrationIntentService.javaonHandleIntent(Intent intent)函数内的示例代码包含获取令牌的行,并使用该令牌订阅主题。
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
                GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

我知道令牌刷新可能是由系统从阅读示例代码 MyInstanceIDListenerService.java 开始的,然后我必须从回调函数 onTokenRefresh() 通知服务器。我发现当我点击通知打开应用程序时,函数 onHandleIntent(Intent intent) 总是被调用,因此注册令牌将再次生成。我的问题是,在 onTokenRefresh() 点时,我可以设置标志来确定是否需要更新服务器并重新订阅主题。但我能否安全地假设令牌在应用程序启动时永远不会更改?

你好,当 onTokenRefresh() 被触发后,我们是否真的需要重新订阅所有主题,还是 GCM 服务器会自动处理? - davidcoder
1个回答

3
“如果应用程序从未更新且InstanceID提供程序从未启动刷新,GCM注册令牌是否保持不变?”
简短回答是是的,它不会改变。如果有更改,则会调用令牌刷新。至于谷歌示例代码中,其中一些关键部分缺失,您需要自己填充。首先是RegistrationIntentService未检查设备是否已注册。您应该将此信息保存在共享首选项中。
如果设备已经注册,则不需要此代码段:
InstanceID instanceID = InstanceID.getInstance(this);
String token =     instanceID.getToken(getString(R.string.gcm_defaultSenderId),
                GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);

现在的问题是,如果您反复执行此代码会发生什么?我进行了实验,并发现有些设备一遍又一遍地返回相同的令牌,而其他设备则返回不同的令牌。


这就是我的问题所在,引用的代码会在我点击通知打开应用程序时每次执行。在我的实验中,令牌似乎保持不变。但是如果它是不同的,那么我将不得不通知服务器并重新订阅。正如您提到的,令牌在某些设备上是不同的。对于这种情况,我需要将当前的标记保存在某个地方,并在每次执行时与新标记进行比较。 - Dino Tw
你的意图肯定有问题吧?这段代码应该只在应用程序生命周期内执行一次。无论如何,在共享首选项中保存一个标志,表明你已经注册过了,就可以避免这个问题。 - e4c5
我目前在我的设备上没有看到问题,因为令牌保持不变。但是你说在其他设备上它将有不同的值,这让我在发布后感到担忧。如果我通过主屏幕上的图标打开应用程序,是的,代码将不会被执行。这只会发生在从通知中打开应用程序时。我可以在函数InstanceIDListenerService.html#onTokenRefresh()中设置标志,但如果更改是从getToken()启动的,我也想知道是否有更好的方法。 - Dino Tw
我所问的是,为什么你不添加四行代码来检查是否已经注册并跳过注册呢? - e4c5
当然,这很容易做到。让我更清楚一些,不同的令牌可能发生在以下两种情况下:1)调用onTokenRrfresh();2)执行getToken()。第一种情况是确定的,因为它由Android系统启动,我可以在这里设置标志。第二种情况会随机发生(据我目前的理解),所以我需要在某个地方记住当前值,并在每次执行时进行比较。在您的实验中,当第二种情况发生时,您是否看到onTokenRrfresh()总是被调用(这意味着只存在第一种情况)?如果是这样,我可以简单地依赖于onTokenRrfresh()来设置标志。 - Dino Tw

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