Подтвердить что ты не робот

Регистр облачных сообщений Google AUTHENTICATION_FAILED

Я хочу попробовать службу Google Cloud Messaging (GCM), и я столкнулся с проблемой в начале.

Я получаю сообщение об ошибке AUTHENTICATION_FAILED при попытке зарегистрировать устройство в GCM. Я искал, и все, что я нашел, это варианты неправильного пароля. Мой пароль правильный, и я использую только одну учетную запись.

Существует два способа внедрения GCM-клиента на Android:

  • Библиотека GCM с дополнительной банкой, теперь устарела.
  • API сервисов Google Play

Я начал со второго, конечно, и получил эту проблему.

Я думал, что проблема в моем телефоне, но потом решил попробовать первый способ, который сработает! Однако он устарел и требует дополнительной банки, что не похоже на правильный путь.

В попытке понять причины ошибки я декомпилировал банку Google Play Services и сравнил ее с библиотекой 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 Services (я думаю), и она работает!

В банке API сервисов Google Play это com.google.android.gms, и он не работает (ошибка AUTHENTICATION_FAILED).

Затем в библиотеке GCM я заменил "gsf" на "gms" и запустил. И у меня такая же ошибка AUTHENTICATION_FAILED! Если я вхожу в другой пакет, то он не работает.

Что мне нужно сделать, чтобы он работал? Должен ли я настроить что-то в телефоне? Или это ошибка в сервисах Google Play? Кто-нибудь столкнулся с такой проблемой?

Спасибо заранее!

4b9b3361

Ответ 1

Я столкнулся с той же проблемой, и, похоже, Google не спешит ее исправлять.

Я не хотел добавлять устаревшего хелпера 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;
    }
}

Я добавил указанный выше код в свое приложение. Это упрощенные методы из Client Helper gcm.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. Поскольку вы видите только около 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>

Надеюсь, это поможет, пока Google не начнет действовать вместе!

Ответ 2

Это похоже на ошибку. Вот о чем говорит разработчик Android в андроид-gcm Google Group:

Некоторые предпосылки: регистрация Froyo и Gingerbread осуществляется в GoogleServicesFramework, используя учетную запись Google для регистрации. Это привело к множеству ошибок auth для людей, где учетная запись был не в хорошем состоянии.

Начиная с ICS, GCM не зависит или использует учетную запись Google - вы может использовать его перед добавлением учетной записи или без каких-либо учетных записей.

Обновление "Службы воспроизведения" реализует новую схему для всех устройств - но, похоже, небольшое количество устройств имеет проблемы с это, мы расследуем - но цифры намного ниже, чем те со старой схемой.

Если вы хотите использовать код в GSF, для Froyo и Gingerbread - вы необходимо использовать предыдущую библиотеку, которая явно задает имя пакета.В новой библиотеке GCM используется новый регистрационный код.

Фактическое подключение к Google происходит по тому же пути - мы постепенно (и медленно) перемещение устройств в новый код в игре Сервисы.

До сих пор у меня есть 2 отчета об ошибках, и у нас есть несколько подозреваемых. Мы знаем это если устройство не подключено в течение > 9 месяцев, это будет в этом состояние и factory reset.

У нас были некоторые отчеты, в которых factory reset не решила проблему - но у меня нет ошибок или информации, чтобы подтвердить или проследить это. только случай, когда я определил, где factory reset не помогло бы, если телефон отправляет плохую информацию на сервер в начальной регистрации - мы добавляем дополнительные проверки для этого.

По-видимому, a factory reset может решить проблему, но они все еще следят.

Ответ 3

Таким образом, похоже, что решение избежать этой проблемы - вернуться к старой устаревшей клиентской библиотеке GCM в случае ошибки AUTHENTICATION_FAILED на FROYO и GINGERBREAD.

Вот простой фрагмент кода о том, как я обновил новый клиент Gcm для резервного копирования старого клиента:

@Override
protected void onPostExecute(Integer resultCode) {

    if(resultCode == EXCEPTION_THROWED) {

        //Android 2.2 gmc bug http://stackoverflow.com/info/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, чтобы попытаться вспомнить, что я не использую его для других вещей.