В API GoogleCloudMessaging, как обрабатывать обновление или истечение срока действия регистрационного удостоверения?

Как говорится в этом вопросе, как узнать, когда идентификатор регистрации стал недействительным в API GoogleCloudMessaging ? Я уже читал ответы на несколько вопросов по аналогичной теме: истекает ли идентификатор регистрации GCM? И Google Coud Mesaging (GCM) и registration_id истекает, как я узнаю? , Проблема с этим вопросом заключается в том, что ответы есть для C2DM или старого GCM API, который использовал GCMRegistrar вместо API GoogleCloudMessaging. Предыдущие два метода были обесценены.

Я постараюсь сломать свою путаницу / вопрос поэтапно :

1) Под заголовком « Включить GCM» во втором пункте говорится:

Google may periodically refresh the registration ID, so you should design your Android application with the understanding that the com.google.android.c2dm.intent.REGISTRATION intent may be called multiple times. Your Android application needs to be able to respond accordingly.

The registration ID lasts until the Android application explicitly unregisters itself, or until Google refreshes the registration ID for your Android application. Whenever the application receives a com.google.android.c2dm.intent.REGISTRATION intent with a registration_id extra, it should save the ID for future use, pass it to the 3rd-party server to complete the registration, and keep track of whether the server completed the registration. If the server fails to complete the registration, it should try again or unregister from GCM.

2) Теперь, если это так, тогда я должен обработать намерение в BroadcastReceiver и отправить запрос register () еще раз, чтобы получить новый идентификатор регистрации. Но проблема в том, что на той же странице под заголовком ERROR_MAIN_THREAD говорится, что: GCM methods are blocking. You should not run them in the main thread or in broadcast receivers GCM methods are blocking. You should not run them in the main thread or in broadcast receivers .

3) Я также понимаю, что при изменении идентификатора регистрации существуют другие два сценария (как указано в разделе «Дополнительные темы под заголовком« Сохранение состояния регистрации в синхронизации » ):« Обновление приложения и резервное копирование и восстановление ». Я уже обрабатываю их при открытии приложения.

4) В GCMRegistrar API внутри GCMBaseIntentService использовался обратный вызов методаRegistered () , который вызывался при регистрации устройства. Здесь я использовал для сохранения идентификатора регистрации и отправки на сторонние серверы.

Но теперь, как мне обрабатывать обновление или обновление идентификатора регистрации, сохранять его и отправлять на сторонний сервер?

Возможно, я либо смущаюсь, читая все это, либо что-то упускаю. Я был бы очень благодарен за вашу помощь.

Обновить

Даже при изменении регистрационных идентификационных изменений в облачных сообщениях Google в потоке Android не упоминается, как обрабатывать периодическое обновление идентификатора Google?

Я даю то, что я реализовал в своей заявке

 @Override protected void onRegistered(Context context, String registrationId) { Log.i(TAG, "Device registered: regId = " + registrationId); //displayMessage(context, getString(R.string.gcm_registered)); //ServerUtilities.register(context, registrationId); //1. Store this id to application Prefs on each request of device registration //2. Clear this id from app prefs on each request of device un-registration //3. Now add an if check for new registartion id to server, you can write a method on server side to check if this reg-id matching for this device or not (and you need an unique identification of device to be stored on server) //4. That method will clear that if id is matching it meanse this is existing reg-id, and if not matching this is updated reg-id. //5. If this is updated reg-id, update on server and update into application prefs. } 

Вы можете сделать это так же

 if reg_id exists_into prefrences then if stored_id equals_to new_reg_id then do nothing else say server to reg_id updated update prefrences with new id end if else update this id to application prefs say server that your device is registered end if 

Но проблема возникает, когда пользователь очищает данные приложения, и вы потеряете текущий reg-id.


Обновление для нового примера API. Кредиты относятся к изменениям идентификатора регистрации Eran и его ответа в Google Cloud Messaging на Android

Google изменил свое демо-приложение, чтобы использовать новый интерфейс. Они обновляют идентификатор регистрации, устанавливая дату истечения срока действия, сохраненное локально приложением. Когда приложение запускается, они загружают свой локально сохраненный идентификатор регистрации. Если он «истек» (который в демо означает, что он был получен от GCM более 7 дней назад), они gcm.register(senderID) называют gcm.register(senderID) .

Это не относится к гипотетическому сценарию, в котором идентификатор регистрации обновляется Google для приложения, которое не было запущено в течение длительного времени. В этом случае приложение не будет знать об изменениях, и ни один из сторонних серверов.

 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mDisplay = (TextView) findViewById(R.id.display); context = getApplicationContext(); regid = getRegistrationId(context); if (regid.length() == 0) { registerBackground(); } gcm = GoogleCloudMessaging.getInstance(this); } /** * Gets the current registration id for application on GCM service. * <p> * If result is empty, the registration has failed. * * @return registration id, or empty string if the registration is not * complete. */ private String getRegistrationId(Context context) { final SharedPreferences prefs = getGCMPreferences(context); String registrationId = prefs.getString(PROPERTY_REG_ID, ""); if (registrationId.length() == 0) { Log.v(TAG, "Registration not found."); return ""; } // check if app was updated; if so, it must clear registration id to // avoid a race condition if GCM sends a message int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE); int currentVersion = getAppVersion(context); if (registeredVersion != currentVersion || isRegistrationExpired()) { Log.v(TAG, "App version changed or registration expired."); return ""; } return registrationId; } /** * Checks if the registration has expired. * * <p>To avoid the scenario where the device sends the registration to the * server but the server loses it, the app developer may choose to re-register * after REGISTRATION_EXPIRY_TIME_MS. * * @return true if the registration has expired. */ private boolean isRegistrationExpired() { final SharedPreferences prefs = getGCMPreferences(context); // checks if the information is not stale long expirationTime = prefs.getLong(PROPERTY_ON_SERVER_EXPIRATION_TIME, -1); return System.currentTimeMillis() > expirationTime; } 

Просто добавлю ответ Панкаджа:

  • This(the example on getting started documents by Google) doesn't handle the hypothetical scenario in which a registration ID is refreshed by Google for an app that hasn't been launched for a long time. In that case, the app won't be aware of the change, and neither will the 3rd party server.

    Его правда, что пример документации Getting Starting не обрабатывает этот случай. Поэтому разработчик должен справиться сам.

  • Также в ответе говорится, что They refresh the registration ID by setting an expiration date on the value persisted locally by the app. When the app starts, they load their locally stored registration id. If it is "expired" they call gcm.register(senderID) again. They refresh the registration ID by setting an expiration date on the value persisted locally by the app. When the app starts, they load their locally stored registration id. If it is "expired" they call gcm.register(senderID) again.

    Проблема заключается в том, что семидневный срок действия registration ID в образце заключается в том, чтобы избежать сценария, когда устройство отправляет регистрацию на сторонний сервер, но сервер теряет его. Он не обрабатывает обновление идентификатора с серверов Google.

  • Второй пункт под заголовком « Enable GCM на странице « Обзор архитектуры» гласит:

    Note that Google may periodically refresh the registration ID, so you should design your Android application with the understanding that the com.google.android.c2dm.intent.REGISTRATION intent may be called multiple times. Your Android application needs to be able to respond accordingly.

    Таким образом, для обработки вам нужно иметь широковещательный прослушиватель, который может обрабатывать намерение com.google.android.c2dm.intent.REGISTRATION , которое Google отправляет в приложение, когда ему нужно обновить идентификатор регистрации.

  • Есть еще одна часть вопроса, в котором говорится о the problem is that inside the Broadcast Listener I cannot call register the for Push ID again. This is because the the problem is that inside the Broadcast Listener I cannot call register the for Push ID again. This is because the документации написано: GCM methods are blocking. You should not run them in the main thread or in broadcast receiver GCM methods are blocking. You should not run them in the main thread or in broadcast receiver .

    Я думаю, что этот вопрос полностью отличается от заявления. Когда вы зарегистрируете широковещательный приемник, у него будет Intent которое будет содержать новый registration ID от Google. Мне НЕ нужно снова вызвать gcm.register() в прослушителе широковещания.

Надеюсь, это поможет кому-то понять, как обращаться с обновлением регистрационного удостоверения.