在 Android 上的 Google Cloud Messaging 中处理注册 ID 更改 [英] Handling registration ID changes in Google Cloud Messaging on Android

查看:16
本文介绍了在 Android 上的 Google Cloud Messaging 中处理注册 ID 更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Google Cloud Messaging 的文档中,它指出:

In the docs on Google Cloud Messaging, it states:

Android 应用程序应存储此 ID 以备后用(对于例如,检查 onCreate() 是否已经注册).笔记Google 可能会定期刷新注册 ID,以便您设计您的 Android 应用程序时应该理解com.google.android.c2dm.intent.REGISTRATION 意图可能会被调用多次.您的 Android 应用程序需要能够响应相应地.

The Android application should store this ID for later use (for instance, to check on onCreate() if it is already registered). Note that Google may periodically refresh the registration ID, so you should design your Android application with the understanding that the com.google.android.c2dm.intent.REGISTRATION intent may be called multiple times. Your Android application needs to be able to respond accordingly.

我使用以下代码注册我的设备:

I register my device using the following code:

GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String regID = gcm.register(senderID);

GoogleCloudMessaging 类封装了注册过程.那么我应该如何处理 com.google.android.c2dm.intent.REGISTRATION 因为处理是由 GoogleCloudMessaging 类在内部完成的?

The GoogleCloudMessaging class encapsulates the registration process. So how am I suppose to handle com.google.android.c2dm.intent.REGISTRATION since handling that is done internally by the GoogleCloudMessaging class?

推荐答案

这是一个有趣的问题.

Google 鼓励您改用新的注册流程:

Google encourage you to switch to the new registration process :

在移动设备上运行的 Android 应用程序通过调用 GoogleCloudMessaging 方法 register(senderID...) 注册接收消息.此方法为 GCM 注册应用程序并返回注册 ID.这种简化的方法取代了之前的 GCM 注册流程.

An Android application running on a mobile device registers to receive messages by calling the GoogleCloudMessaging method register(senderID...). This method registers the application for GCM and returns the registration ID. This streamlined approach replaces the previous GCM registration process.

说明 Google 可能会定期刷新注册 ID 的注释仅出现在仍显示旧注册过程的页面上,因此该注释可能不再相关.

The note that says Google may periodically refresh the registration ID only appears on the page that still shows the old registration process, so it's possible that this note is no longer relevant.

如果您想安全,您仍然可以使用旧的注册流程.或者您可以使用新流程,但另外还有处理 com.google.android.c2dm.intent.REGISTRATION 意图的代码,以确保您在 Google 决定刷新注册ID.

If you want to be safe, you can still use the old registration process. Or you can use the new process, but have in addition the code that handles the com.google.android.c2dm.intent.REGISTRATION intent, in order to make sure you are covered if Google do decide to refresh the registration ID.

也就是说,我从来没有经历过这样的刷新,即使我确实经历过注册 ID 的变化(通常是由于在卸载应用程序然后重新安装后发送通知),旧的注册 ID 仍然有效(导致 Google 响应中发送了规范的注册 ID),因此没有造成任何伤害.

That said, I never experienced such a refresh, and even when I did experience a change in the registration ID (usually as a result of sending a notification after un-installing the app and then re-installing it), the old registration ID still worked (resulting in a canonical registration ID sent in the response from Google), so no harm was done.

编辑(06.06.2013):

Google 更改了他们的 Demo App 使用新界面.他们通过为应用程序在本地保留的值设置到期日期来刷新注册 ID.当应用程序启动时,它们会加载其本地存储的注册 ID.如果它过期"(在演示中意味着它是在 7 天前从 GCM 收到的),他们会再次调用 gcm.register(senderID).

Google changed their Demo App to use the new interface. They refresh the registration ID by setting an expiration date on the value persisted locally by the app. When the app starts, they load their locally stored registration id. If it is "expired" (which in the demo means it was received from GCM over 7 days ago), they call gcm.register(senderID) again.

这无法处理 Google 为长时间未启动的应用刷新注册 ID 的假设情况.在这种情况下,应用程序不会知道更改,第 3 方服务器也不会.

This doesn't handle the hypothetical scenario in which a registration ID is refreshed by Google for an app that hasn't been launched for a long time. In that case, the app won't be aware of the change, and neither will the 3rd party server.

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.

Google changed their Demo App again (two days ago). This time they removed the logic that considers the Registration ID to be expired after 7 days. Now they only refresh the Registration ID when a new version of the app it installed.

编辑(2014 年 4 月 24 日):

为了完整起见,这里是 Costin Manolache 的话(取自 这里),一位参与 GCM 开发的 Google 开发人员,关于此事:

For the sake of completeness, here are the words of Costin Manolache (taken from here), a Google developer involved in the development of GCM, on the matter :

定期"刷新从未发生,注册刷新不包含在新的 GCM 库中.

The 'periodical' refresh never happened, and the registration refresh is not included in the new GCM library.

注册ID变化的唯一已知原因是应用程序的旧错误如果他们在收到消息时自动取消注册得到升级.在此错误修复之前,应用程序仍需要调用register() 升级后,到目前为止注册ID可能会改变这个案例.显式调用 unregister() 通常会改变还有注册ID.

The only known cause for registration ID change is the old bug of apps getting unregistered automatically if they receive a message while getting upgraded. Until this bug is fixed apps still need to call register() after upgrade, and so far the registration ID may change in this case. Calling unregister() explicitly usually changes the registration ID too.

建议/解决方法是生成您自己的随机标识符,例如,另存为共享首选项.在每次应用升级时,您都可以上传标识符和潜在的新注册 ID.这还可以帮助跟踪和调试升级和注册服务器端的变化.

The suggestion/workaround is to generate your own random identifier, saved as a shared preference for example. On each app upgrade you can upload the identifier and the potentially new registration ID. This may also help tracking and debugging the upgrade and registration changes on server side.

这解释了官方 GCM Demo 应用程序的当前实现.使用 GoogleCloudMessaging 类注册时,不应处理 com.google.android.c2dm.intent.REGISTRATION.

This explains the current implementation of the official GCM Demo application. com.google.android.c2dm.intent.REGISTRATION should never be handled when using the GoogleCloudMessaging class to register.

这篇关于在 Android 上的 Google Cloud Messaging 中处理注册 ID 更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆