这是一个有趣的问题。
Google 鼓励您切换到新的注册流程:
在移动设备上运行的 Android 应用程序通过调用 GoogleCloudMessaging 方法 register(senderID...) 来注册接收消息。该方法为 GCM 注册应用程序并返回注册 ID。这种简化的方法取代了以前的 GCM 注册过程。
说的注释Google may periodically refresh the registration ID
只出现在仍然显示旧注册过程的页面上,因此该注释可能不再相关。
如果您想安全,您仍然可以使用旧的注册流程。或者您可以使用新流程,但另外还有处理com.google.android.c2dm.intent.REGISTRATION
意图的代码,以确保如果 Google 确实决定刷新注册 ID,您会被覆盖。
也就是说,我从来没有经历过这样的刷新,即使我确实经历了注册ID的变化(通常是由于卸载应用程序然后重新安装后发送通知的结果),旧的注册ID仍然存在工作(导致在谷歌的响应中发送一个规范的注册 ID),所以没有造成任何伤害。
编辑(06.06.2013):
Google 更改了他们的Demo App以使用新界面。他们通过在应用程序本地保存的值上设置过期日期来刷新注册 ID。当应用程序启动时,它们会加载其本地存储的注册 ID。如果它“过期”(在演示中意味着它是在 7 天前从 GCM 收到的),他们会gcm.register(senderID)
再次调用。
这不处理 Google 为长时间未启动的应用程序刷新注册 ID 的假设场景。在这种情况下,应用程序不会知道更改,第三方服务器也不会。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mDisplay = (TextView) findViewById(R.id.display);
context = getApplicationContext();
regid = getRegistrationId(context);
if (regid.length() == 0) {
registerBackground();
}
gcm = GoogleCloudMessaging.getInstance(this);
}
/**
* Gets the current registration id for application on GCM service.
* <p>
* If result is empty, the registration has failed.
*
* @return registration id, or empty string if the registration is not
* complete.
*/
private String getRegistrationId(Context context) {
final SharedPreferences prefs = getGCMPreferences(context);
String registrationId = prefs.getString(PROPERTY_REG_ID, "");
if (registrationId.length() == 0) {
Log.v(TAG, "Registration not found.");
return "";
}
// check if app was updated; if so, it must clear registration id to
// avoid a race condition if GCM sends a message
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion(context);
if (registeredVersion != currentVersion || isRegistrationExpired()) {
Log.v(TAG, "App version changed or registration expired.");
return "";
}
return registrationId;
}
/**
* Checks if the registration has expired.
*
* <p>To avoid the scenario where the device sends the registration to the
* server but the server loses it, the app developer may choose to re-register
* after REGISTRATION_EXPIRY_TIME_MS.
*
* @return true if the registration has expired.
*/
private boolean isRegistrationExpired() {
final SharedPreferences prefs = getGCMPreferences(context);
// checks if the information is not stale
long expirationTime =
prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1);
return System.currentTimeMillis() > expirationTime;
}
编辑(08.14.2013):
Google 再次更改了他们的Demo App(两天前)。这次他们删除了认为注册 ID 将在 7 天后过期的逻辑。现在他们只在安装新版本的应用程序时刷新注册 ID。
编辑(04.24.2014):
为完整起见,以下是参与 GCM 开发的 Google 开发人员Costin Manolache(摘自此处)在此问题上的话:
“定期”刷新从未发生,并且注册刷新不包含在新的 GCM 库中。
注册 ID 更改的唯一已知原因是应用程序在升级时收到消息会自动取消注册的旧错误。在修复此错误之前,应用程序在升级后仍然需要调用 register(),并且到目前为止注册 ID 可能会在这种情况下发生变化。显式调用 unregister() 通常也会更改注册 ID。
建议/解决方法是生成您自己的随机标识符,例如保存为共享首选项。在每次应用升级时,您都可以上传标识符和可能的新注册 ID。这也可能有助于跟踪和调试服务器端的升级和注册更改。
这解释了官方 GCM Demo 应用程序的当前实现。
使用类注册com.google.android.c2dm.intent.REGISTRATION
时千万不要处理。GoogleCloudMessaging