处理Android上的谷歌云信息注册ID的变化信息、Android、谷歌云、ID

2023-09-11 11:26:26 作者:同行.

在对谷歌云消息传递的文档,它规定:

In the docs on Google Cloud Messaging, it states:

Android的应用程序应该存储此ID供以后使用(   例如,要检查的onCreate(),如果它已经被注册)。注意   ,谷歌可能会定期刷新注册ID,所以你   应该设计自己的Andr​​oid应用程序的理解是,   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.

我用下面的code寄存器我的设备:

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 encourage you to switch to the new registration process :

在移动设备上运行的Andr​​oid应用程序注册通过调用GoogleCloudMessaging方法寄存器接收消息(senderID ...)。此方法注册申请GCM和返回的注册ID。这种简化的方法代替了previous 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.

本笔记,上面写着谷歌可能会定期刷新注册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.

如果你想成为安全的,你仍然可以使用旧的注册过程。或者你也可以使用新的过程,但在另外的code处理该 com.google.android.c2dm.intent.REGISTRATION 的意图,为了使一定要覆盖,如果谷歌真的决定要刷新的注册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仍然工作(导致来自谷歌的反应发出了规范的注册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.

修改(2013年6月6日):

谷歌改变了他们的Demo应用使用新界面。他们刷新注册ID通过设置上由应用局部持久的值的有效期限。当应用程序启动时,它们加载它们的本地存储的注册ID。如果是过期,他们叫 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.

这不处理的假想方案,其中,注册ID是由谷歌对于尚未推出很长一段时间的应用程序更新。在这种情况下,该应用将不知道的改变,也不将第三方服务器

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;
}

修改(2013年8月14日):

谷歌改变了他们的Demo应用试(两天前)。这一次,他们移除考虑注册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日):

有关为了完整起见,下面是斯丁Manolache的词语(从here),谷歌的开发者参与GCM的发展,对此事:

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库

谷歌为Android用户推出手机自动备份功能

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

目前已知的唯一原因注册ID的变化是应用程序的老错误   越来越如果他们接受,而消息会自动注销   越来越升级。到这个bug是固定的应用程序仍需要调用   注册()升级后,迄今的注册ID可能会改变   这个案例。调用注销()显式地通常改变   注册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.

的建议/解决办法是生成自己的随机标识符,   保存作为一个共享preference例如。在每个应用程序的升级,你可以   载的标识符和潜在的新的注册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演示应用程序的当前执行。 com.google.android.c2dm.intent.REGISTRATION 不应该使用 GoogleCloudMessaging 类注册时进行处理。

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.