在处理谷歌云端通讯在Android上注册ID的变化在处理谷歌云端通讯在Android上注册ID的变化

2019-05-08 15:29发布

在谷歌上的云信息的文档,它指出:

Android的应用程序应该保存这个ID,供以后使用(例如,去检查的onCreate(),如果它已经被注册)。 请注意,谷歌可能会定期刷新的注册ID,所以你应该设计自己用的是com.google.android.c2dm.intent.REGISTRATION意图可能被多次调用的理解Android应用程序。 你的Android应用程序需要能够作出相应的反应。

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

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

在Google云端通讯类封装注册过程。 所以,我怎么想处理com.google.android.c2dm.intent.REGISTRATION因为处理一个由Google云端通讯类内部做了什么?

Answer 1:

这是一个有趣的问题。

谷歌鼓励你切换到新的注册过程:

在移动设备上运行的应用程序的Android寄存器通过调用Google云端通讯方法寄存器接收消息(senderID ...)。 此方法注册用于GCM的应用和返回的注册ID。 这种简化的方法取代了以前的GCM注册过程。

,说该说明Google may periodically refresh the registration ID只出现仍然显示旧的注册过程的页面上,所以它可能是这个音符不再相关。

如果你想成为安全的,你仍然可以使用旧的注册过程。 或者你也可以使用新的过程,但除了有一个处理的代码com.google.android.c2dm.intent.REGISTRATION意图,以确保你覆盖,如果谷歌真的决定要刷新注册ID。

这么说,我从来没有经历过这样的刷新,即使我没有体验到注册ID的变化(通常为发送未安装该应用程序,然后重新安装它后,通知的结果),旧的注册ID还工作(导致在从谷歌响应发送的规范注册ID),所以不伤害被完成。

编辑(2013年6月6日):

谷歌改变了他们的演示应用使用新界面。 它们通过设置在由该应用局部持续值的期满日期刷新注册ID。 当应用程序启动时,他们加载其本地存储的注册ID。 如果是“过期”(在演示意味着它是从GCM超过7天前收到的),他们称之为gcm.register(senderID)一次。

这不处理,其中注册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;
}

编辑(2013年8月14日):

谷歌改变了他们的演示应用再次(两天前)。 这个时候,他们移除考虑了注册ID到7天后到期的逻辑。 现在,他们只刷新,当应用程序的新版本,它安装的注册ID。

编辑(2014年4月24日):

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

该“定期”刷新从来没有发生过,而注册刷新不包括在新的GCM库。

登记ID改变的唯一已知的原因是应用程序的自动获得未登记,如果他们接受而得到升级的消息旧错误。 到这个bug是固定的应用程序仍然需要调用注册()升级后,迄今的注册ID可能会在这种情况下发生改变。 调用取消注册()明确地通常改变注册ID太。

建议/解决方法是生成自己的随机标识符,保存为例如一个共享的偏好。 在每个应用程序的升级,你可以上传标识符和潜在的新注册ID。 这也可以帮助跟踪和调试服务器端升级和变更登记。

这说明目前执行的GCM官方演示应用。 com.google.android.c2dm.intent.REGISTRATION使用时,不应该被处理GoogleCloudMessaging类注册。



Answer 2:

阅读新的实例id API,我发现当令牌可能会更改的详细信息:

如使用为gettoken()方法需要您的应用程序可以从实例ID服务请求令牌,像实例id,你的应用程序也可以存储在自己的服务器上标记。 发给你的应用程序的所有令牌属于应用程序的实例id。

令牌是独一无二的,安全的,但是当用户卸载和设备恢复期间重新安装你的应用程序您的应用程序或实例ID服务可能需要刷新令牌的安全性问题或事件 。 您的应用程序必须实现一个监听器,响应令牌从实例ID服务刷新请求。

更多细节:

实例ID服务启动定期回调(例如,每6个月),请求您的应用程序刷新其令牌。 它也可以当发起回调:

  • 有安全问题; 例如,SSL或平台的问题。
  • 设备信息不再有效; 例如,备份和恢复。
  • 实例ID服务,否则影响。

资料来源:

https://developers.google.com/instance-id/

https://developers.google.com/instance-id/guides/android-implementation



Answer 3:

通过跨网误导性的答案,包括SO吨擦洗后,唯一的地方,我发现了一个完整的答案是由伊兰的答案,并说在这里 :

虽然自动注册刷新可能会或可能永远不会发生,谷歌描述了simiple算法通过解析成功的响应处理canocical_ids:

If the value of failure and canonical_ids is 0, it's not necessary to parse the remainder of the response. Otherwise, we recommend that you iterate through the results field and do the following for each object in that list:

If message_id is set, check for registration_id:
If registration_id is set, replace the original ID with the new value (canonical ID) in your server database. Note that the original ID is not part of the result, so you need to obtain it from the list of code>registration_ids passed in the request (using the same index).
Otherwise, get the value of error:
If it is Unavailable, you could retry to send it in another request.
If it is NotRegistered, you should remove the registration ID from your server database because the application was uninstalled from the device or it does not have a broadcast receiver configured to receive com.google.android.c2dm.intent.RECEIVE intents.
Otherwise, there is something wrong in the registration ID passed in the request; it is probably a non-recoverable error that will also require removing the registration from the server database. See Interpreting an error response for all possible error values.

从上述链接。



文章来源: Handling registration ID changes in Google Cloud Messaging on Android