Регистр облачных сообщений 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? Кто-нибудь столкнулся с такой проблемой?
Спасибо заранее!
Ответы
Ответ 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, чтобы попытаться вспомнить, что я не использую его для других вещей.