谷歌云消息注册AUTHENTICATION_FAILED



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

我在尝试将设备注册到 GCM 时AUTHENTICATION_FAILED出错。我搜索了一下,我发现的只是错误密码的变体。我的密码是正确的,我只使用一个帐户。

有两种

方法可以在 Android 上实现 GCM 客户端:

  1. 带有附加 jar 的 GCM 库,现已弃用。
  2. 谷歌播放服务接口

我当然从第二个开始,遇到了这个问题。

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

为了理解错误的原因,我反编译了Google Play服务jar并将其与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服务框架(我猜(,它可以工作!

在Google Play服务API jar中它是com.google.android.gms的,并且它不起作用(AUTHENTICATION_FAILED错误(。

然后在GCM库中,我将"gsf"替换为"gms"并运行。我得到了同样的AUTHENTICATION_FAILED错误!如果我输入另一个包,那么它不起作用。

我需要做什么才能使其正常工作?我应该在手机中设置一些东西吗?还是谷歌播放服务中的错误?有人遇到过这样的问题吗?

提前感谢!

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

我不想将已弃用的客户端助手 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();
            }

AUTHENTICATION_FAILED触发上述代码中的 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 添加到应用中(

protected void onHandleIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    if (extras != null && !extras.isEmpty()) {  // has effect of unparcelling Bundle
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        String messageType = gcm.getMessageType(intent);
        if (messageType != null) {
            if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
                showMessage(extras.getString("message")); // call your code
                Logger.d(TAG, "Received message: " + message.alert + ": " + message.url);
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
                Logger.e(TAG, "Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
                Logger.e(TAG, "Deleted messages on server: " + extras.toString());
            }
        } else {
            String regID = extras.getString("registration_id");
            if (regID != null && !regID.isEmpty()) {
                doRegistration(regID); // send to your server etc.
                GCMSetup.storeRegistrationId(regID);
                GCMSetup.cancelRegCallbackIntent();
            }
        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    GCMBroadcastReceiver.completeWakefulIntent(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>

我希望这有所帮助,直到谷歌一起采取行动!

似乎是一个错误。以下是Android开发人员在android-gcm Google Group中对此的评价:

一些背景:弗罗约和姜饼注册在 GoogleServicesFramework,使用 Google 帐户进行注册。 这导致帐户的人出现很多身份验证错误 状态不好。

从 ICS 开始,GCM 不依赖或使用 Google 帐户 - 您 可以在添加帐户之前使用它,也可以在没有任何帐户的情况下使用它。

"Play 服务"更新正在所有设备上实施新方案 设备 - 但似乎少数设备存在问题 我们正在调查这一点 - 但数字远低于那些 用旧的方案。

如果您想在 GSF 中使用代码,用于 Froyo 和姜饼 - 您 需要使用以前的库,该库显式设置包名称。 GCM 中的新库正在使用新的注册码。

与谷歌的实际连接遵循相同的路径 - 我们正在 逐渐(和缓慢地(将设备移动到运行中的新代码 服务业。

到目前为止,我有 2 个错误报告,我们有几个嫌疑人。我们知道 如果设备在>9 个月内未连接,它将处于此状态 状态,并且需要恢复出厂设置。

我们有一些报告,恢复出厂设置并不能解决问题 - 但我没有错误报告或信息来确认或跟踪这一点。这 我确定恢复出厂设置无济于事的唯一情况是,如果 手机在初始签入时向服务器发送错误信息 - 我们正在为此添加额外的检查。

显然,恢复出厂设置可能会解决问题,但他们仍在调查中。

因此,

看起来避免此问题的解决方案是回退到旧的已弃用的 GCM 客户端库,以防 FROYO 和 GINGERBREAD 发生AUTHENTICATION_FAILED错误。

以下是我如何将新的 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 客户端帮助:http://developer.android.com/google/gcm/helper.html

您可以在以下路径上找到计算机上 GCM 客户端的代码:ANDROID_SDK_ROOT/extras/google/gcm-client(假设您已使用Android SDK Manager下载了此额外内容(。

我将旧的gcm客户端放在一个名为com.google.android.gcm.deprecated的新软件包中,以记住自己不要将其用于其他内容。

最新更新