使用两个不同的注册ID进行GCM注册

8

我在客户端/服务器中使用推送通知时遇到了设备注册管理的轻微问题。

问题

我的问题是,当我卸载并重新安装该应用程序时,应用程序返回空字符串以获取注册ID (GCMRegistrar.getRegistrationId(this)),我将其用于注销这个设备。 问题是,我有一个新的、不同的注册ID(有时)但两者都有效!因此,我不知道服务端如何知道它是否属于同一台设备。另外我要说明的是,我没有更改应用程序版本。是否对清单进行的任何更改会触发发放新的注册ID?

在Android方面,我执行以下操作:

    /**
     * 使用GCM向此android设备注册
     */
    private void registerDeviceWithGCM() {
        GCMRegistrar.checkDevice(this);
        GCMRegistrar.checkManifest(this);
        String regId = GCMRegistrar.getRegistrationId(this);
        if (regId.equals("")) {
            log.debug("使用GCM注册应用程序");
            GCMRegistrar.register(this, ApplicationData.SENDER_ID);
        } else {
            log.debug("已注册: " + regId);
            deviceRegistrationService.updateServerRegistrationData(this, regId);
        }
    }

在我的GCMIntentService.java中,我执行以下操作:

    /**
     * 在新设备注册时触发,并使用服务器更新注册信息
     *
     * @param context 来自的环境
     * @param regId   设备的注册ID
     */
    @Override
    protected void onRegistered(Context context, String regId) {
        Log.d(TAG, "注册: " + regId);
        Intent intent = new Intent(RegistrationReceiver.REGISTRATION_INTENT);
        intent.putExtra(RegistrationReceiver.REGISTRATION_ID, regId);
        context.sendBroadcast(intent);
    }

在我的RegistrationReceiver.java中,我有以下内容:

    /**
     * 触发与cirrus的设备注册
     *
     * @param context 未使用
     * @param intent  用于获取注册ID
     */
    @Override
    public void handleReceive(Context context, Intent intent) {
        log.debug("接收到带有意图操作的注册: " + intent.getAction());
        if (intent.getAction().equals(REGISTRATION_INTENT)) {
            String regId = intent.getStringExtra(REGISTRATION_ID);
            log.debug("收到具有注册ID的注册意图: " + regId);
            deviceRegistrationService.updateServerRegistrationData(loginActivity, regId);
        } else if (intent.getAction().equals(REGISTRATION_FAILED_INTENT)) {
            log.debug("接收注册失败意图,显示错误消息");
            showRegistrationFailedMessage(intent);
        }
    }

再次说明,问题是我有两个或更多的注册ID都有效(如果旧的无法从服务器发送消息,那就没问题,因为我可以将其清理掉)。

1个回答

11
有时候Google会更改注册ID,导致您有多个相关的ID。发送通知的服务器(即您的服务器)必须使用新ID更新数据库。
有关更多信息,请查看此文档:http://developer.android.com/google/gcm/adv.html 该文档表示:
在服务器端,只要应用程序表现良好,一切都应该正常工作。但是,如果应用程序中的错误触发了同一设备的多个注册,很难协调状态,并且可能会出现重复消息。
GCM提供了一个名为"规范化注册ID(canonical registration IDs)"的机制,可轻松解决这些情况。规范化注册ID被定义为应用程序请求的最后一个注册ID。这是服务器在向设备发送消息时应该使用的ID。
如果稍后尝试使用不同的注册ID发送消息,则GCM将像往常一样处理请求,但它将在响应的registration_id字段中包括规范化注册ID。请确保将服务器存储的注册ID替换为此规范化ID,因为您正在使用的ID最终将停止工作。

@nunofmendes 但是第一次我能够接收到消息,然后替换之后就无法再获取了。我的问题是如何在第一次也禁用它。 - Kartheek Sarabu
我认为你做不到。第一次是谷歌告诉你“这个改变了,但我们会让它通过。只有这一次。” - nunofmendes
这太愚蠢了。应该有一个标志,允许您接收规范化的ID而通过消息发送。这样,拥有多个ID的人就不会被一条消息轰炸。 - rodrigo-silveira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接