Android Google云消息注册验证失败

Android Google云消息注册验证失败,android,push-notification,google-play,google-cloud-messaging,google-play-services,Android,Push Notification,Google Play,Google Cloud Messaging,Google Play Services,我想尝试谷歌云消息(GCM)服务,一开始我遇到了一个问题 尝试将设备注册到GCM时,我收到一个错误身份验证\u失败。 我搜索了一下,发现的都是错误密码的变体。我的密码是正确的,我只使用一个帐户 在Android上实现GCM客户端有两种方法: 带有附加jar的GCM库,现已弃用 谷歌播放服务API 我从第二个开始,当然,我得到了这个问题 我原以为问题出在我的手机上,但后来决定尝试第一种方法,它奏效了! 但是,它已被弃用,需要一个额外的jar,这似乎不是正确的方法 为了理解错误的原因,我反编译了Go

我想尝试谷歌云消息(GCM)服务,一开始我遇到了一个问题

尝试将设备注册到GCM时,我收到一个错误
身份验证\u失败。
我搜索了一下,发现的都是错误密码的变体。我的密码是正确的,我只使用一个帐户

在Android上实现GCM客户端有两种方法:

  • 带有附加jar的GCM库,现已弃用
  • 谷歌播放服务API
  • 我从第二个开始,当然,我得到了这个问题

    我原以为问题出在我的手机上,但后来决定尝试第一种方法,它奏效了! 但是,它已被弃用,需要一个额外的jar,这似乎不是正确的方法

    为了理解错误的原因,我反编译了GooglePlayServicesJAR,并将其与GCM库进行了比较

    事实证明,他们都有类似的方法,比如:

    void register(Context context, String senderIds) {
        Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
        intent.setPackage("com.google.android.gms"); // this one row are different
        setPackageNameExtra(context, intent);
        intent.putExtra("sender", senderIds);
        context.startService(intent);
    }
    
    一行中的差异:

    在GCM库中,它是
    com.google.android.gsf
    ,其中
    gsf
    是谷歌服务框架(我猜),它可以工作

    在Google Play Services API jar中,它是
    com.Google.android.gms
    ,不起作用(身份验证失败错误)

    然后在GCM库中,我将“gsf”替换为“gms”并运行。我得到了同样的身份验证失败错误!如果我输入另一个包,则它不工作

    我需要做什么才能让它工作?我应该在电话里设置什么吗?还是Google Play服务中的一个bug?有人遇到过这样的问题吗


    提前谢谢

    这似乎是一个bug。以下是一位Android开发人员在

    一些背景:Froyo和Gingerbread注册是在 Google服务框架,使用Google帐户进行注册。 这导致帐户所在的用户出现许多身份验证错误 他的状态不好

    从ICS开始,GCM不依赖或使用Google帐户-你 可以在添加帐户之前使用它,也可以不添加任何帐户

    “播放服务”更新正在所有服务器上实施新方案 设备-但似乎有少数设备存在问题 对此,我们正在调查——但数字远远低于这些数字 用老办法

    如果您想使用GSF中的代码,请使用Froyo和Gingerbread-you 需要使用上一个库,该库显式设置包名。 GCM中的新库正在使用新的注册码

    与谷歌的实际连接遵循相同的路径-我们 逐渐(缓慢)将设备移动到正在使用的新代码 服务

    到目前为止,我有两个错误报告,我们有几个嫌疑犯。我们知道 如果设备未连接超过9个月,它将处于这种状态 状态,需要进行出厂重置

    我们有一些报告称,工厂重置并没有解决问题- 但我没有错误报告或信息来证实或追踪这一点。这个 我发现的唯一一种情况是,如果 手机在初始签入时向服务器发送错误信息 -我们正在为此增加额外的支票


    显然,工厂重置可以解决问题,但他们仍在调查中。

    因此,避免此问题的解决方案似乎是退回到旧的不推荐的GCM客户端库,以防在FROYO和GINGERBREAD上发生身份验证失败错误

    以下是我如何将新Gcm客户端升级为回退以使用旧客户端的简单代码片段:

    @Override
    protected void onPostExecute(Integer resultCode) {
    
        if(resultCode == EXCEPTION_THROWED) {
    
            //Android 2.2 gmc bug http://stackoverflow.com/questions/19269607/google-cloud-messaging-register-authentication-failed
    
            //fall back to old deprecated GCM client library
    
            GCMRegistrar.checkDevice(StartActivity.this);
            GCMRegistrar.checkManifest(StartActivity.this);
            final String registrationId = GCMRegistrar.getRegistrationId(StartActivity.this);
            if (registrationId.equals("")) {
                GCMRegistrar.register(StartActivity.this, SENDER_ID);
            }
    
            //Toast.makeText(context, "Orders and menus won't be sync with other devices since GoogleCloudMessaging is not working correctly on this device. Please notify the developer.", Toast.LENGTH_LONG).show();
    
        }
    
    }
    您可以在此处找到旧的不推荐使用的GCM客户端帮助程序:

    您可以通过以下路径在计算机上找到GCM客户端的代码: ANDROID_SDK_ROOT/extras/google/gcm客户端(假设您已使用ANDROID SDK管理器下载了此额外的软件)


    我将旧的gcm客户端放在一个名为com.google.android.gcm.deprecated的新包中,以提醒自己不要将其用于其他东西。

    我遇到了同样的问题,谷歌似乎并不急于修复它

    我不想将不推荐使用的客户端助手gcm.jar添加到我的应用程序中,因此我编写了一个最低限度的解决方案,它可以在我的Android 2.3.6 Nexus One手机上运行,但注册失败,如上所述

                try {
                    gcm = GoogleCloudMessaging.getInstance(context);
                    regID = gcm.register(SENDER_ID);
                    storeRegistrationId(regID);
                    msg = "Device registered, registration ID=" + regID;
    
                    sendRegistrationIdToBackend();
                } catch (IOException ex) {
                    msg = "Exception registering for GCM :" + ex.getMessage();
                    // If there is an error, don't just keep trying to register.
                    oldSchoolRegister();
                }
    
    身份验证失败会触发上面代码中的IOException

    private void oldSchoolRegister() {
        Intent intent = new Intent("com.google.android.c2dm.intent.REGISTER");
        intent.setPackage("com.google.android.gsf");
        setRegCallbackIntent(context, intent);
        intent.putExtra("sender", SENDER_ID);
        context.startService(intent);
    }
    
    private static synchronized void setRegCallbackIntent(Context context, Intent intent) {
        regCallback = PendingIntent.getBroadcast(context, 0, new Intent(), 0);
        intent.putExtra("app", regCallback);
    }
    
    public static synchronized void cancelRegCallbackIntent() {
        if (regCallback != null) {
            regCallback.cancel();
            regCallback = null;
        }
    }
    
    我将上述代码添加到我的应用程序中。它们是来自客户端助手gcm.jar的简化方法(因此您不需要将jar添加到应用程序中)

    此代码位于intent服务中,有几行代码用于存储从GCM收到的ID。与基本实现相比,您只能看到大约20行额外的代码,并且没有额外的依赖项!您只需更新AndroidManifest.xml,以确保能够收到注册意图

        <receiver android:name="com.camiolog.android.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <category android:name="com.camiolog.android"/>
            </intent-filter>
        </receiver>
    
    
    

    我希望这会有帮助,直到谷歌采取行动

    谢谢,我不想做工厂重置。我将在另一台设备上检查它。在情况得到解决之前,我将使用旧库,或者两者都使用。我不确定我是否理解清除regcallback PendingEvent的必要性,因为这种意图似乎没有任何作用,我不知道您如何能够从接收注册意图的广播接收器调用该例程?regCallback是静态类变量吗?想知道您是否可以创建它,传递它,然后立即取消它,或者甚至不在开始的意图中包含额外的内容。你知道com.google.android.gsf软件包是否需要额外的“应用程序”吗?
        <receiver android:name="com.camiolog.android.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
                <category android:name="com.camiolog.android"/>
            </intent-filter>
        </receiver>