当前位置: 首页 > 面试题库 >

在Android上处理Google Cloud Messaging中的注册ID更改

李安歌
2023-03-14
问题内容

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

Android应用程序应存储此ID供以后使用(例如,检查onCreate()是否已注册)。请注意,Google可能会定期刷新注册ID,因此您在设计android应用程序时应了解com.google.android.c2dm.intent.REGISTRATION意图可能会多次调用。您的Android应用程序需要能够做出相应的响应。

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

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

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


问题答案:

这是一个有趣的问题。

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仍然起作用(导致Google响应中发送了规范的注册ID),因此没有造成任何伤害。

编辑(06.06.2013):

Google更改了其演示应用程序以使用新界面。他们通过在应用程序本地保留的值上设置过期日期来刷新注册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再次更改了他们的演示应用程序(两天前)。这次,他们删除了认为注册ID在7天后过期的逻辑。现在,他们仅在安装新版本的应用程序时刷新注册ID。

编辑(04.24.2014):

为了完整起见,这里是海东青Manolache(摘自的话在这里),谷歌的开发者参与GCM的发展,对此事:

从未发生过“定期”刷新,并且新GCM库中不包括注册刷新。

注册ID更改的唯一已知原因是应用程序的旧错误,如果它们在升级时收到消息,则会自动取消注册。在修复此错误之前,应用程序仍需要在升级后调用register(),到目前为止,在这种情况下,注册ID可能会更改。通常显式调用unregister()通常也会更改注册ID。

建议/解决方法是生成您自己的随机标识符,例如,保存为共享首选项。在每次应用升级时,您都可以上传标识符和可能的新注册ID。这也可能有助于跟踪和调试服务器端的升级和注册更改。

这说明了官方GCM演示应用程序的当前实现。 com.google.android.c2dm.intent.REGISTRATION使用GoogleCloudMessaging该类进行注册时,切勿处理。



 类似资料:
  • 问题内容: 如问题所述,如何确定何时在GoogleCloudMessaging API中注册ID无效?我已经阅读了有关类似主题的几个问题的答案:GCM注册ID是否过期?以及Google Coud Mesaging(GCM)和registration_id到期,我怎么知道?。这些问题的问题在于,答案是使用GCMRegistrar而不是GoogleCloudMessaging API的旧GCMAPI。

  • 在谷歌云消息的文档中,它指出: Android应用程序应该存储此ID以供以后使用(例如,如果已注册,请检查oncreate())。请注意,Google可能会定期刷新注册ID,因此您应该在设计Android应用程序时了解com.google.android.c2dm.intent.注册意图可能会被多次调用。您的Android应用程序需要能够相应地响应。 我使用以下代码注册我的设备: GoogleCl

  • 我想知道如何将应用程序/设备通知,如果GCM服务器决定刷新之前从GCM服务器检索的应用程序的注册ID。目前,我保存第一个检索到的注册ID,并将其保存在数据库中,并将此注册ID发送到应用服务器。所以,从下一次应用程序将不会说话的GCM服务器。在这种情况下,应用程序永远不会知道注册ID是否被GCM服务器更改。谷歌文件提出了一些处理此案的建议,但没有提到应该采取什么步骤。引用谷歌- 虽然是com。谷歌。

  • 我在一个数据库表中有一个GCM注册用户列表及其相应的注册ID,我实际上想在用户从表中删除时注销该用户。我在Stackoverflow中发现了很多示例,但大多数示例都基于旧的GCMRegistarAPI,现在已经不推荐使用了。我正在使用GoogleCloudMessaging API,并通过以下方法注册用户: 我有一个管理员应用程序,它充当第三方应用程序服务器,因为它向所有用户推送通知。我想注销一个

  • 注册表是Windows系统的关键要素之一。 它包含有关操作系统各个方面的大量信息。 几乎所有安装在Windows系统上的应用程序都以某种形式与注册表交互。 注册表包含两个基本元素:键和值。 注册表项是与文件夹类似的容器对象。 注册表值是与文件类似的非容器对象。键可能包含值或其他键。 使用类似于Windows路径名称的语法来引用键,并使用反斜杠来指示层次结构的级别。 本章介绍查询值,添加,删除和编辑

  • 我跟着http://developer.android.com/guide/google/gcm/gs.html#server-在我的应用程序中实现GCM的应用程序 返回空字符串作为注册ID,还需要什么来获得注册ID??