Ответ 1
Это интересный вопрос.
Google предлагает вам перейти на новый процесс регистрации:
Приложение Android, работающее на мобильном устройстве, регистрируется для приема сообщений, вызывая регистр метода GoogleCloudMessaging (senderID...). Этот метод регистрирует приложение для GCM и возвращает идентификатор регистрации. Этот оптимизированный подход заменяет предыдущий процесс регистрации GCM.
Заметка, в которой указано Google may periodically refresh the registration ID
, появляется только на странице, которая все еще показывает старый процесс регистрации, поэтому возможно, что эта заметка больше не актуальна.
Если вы хотите быть в безопасности, вы все равно можете использовать старый процесс регистрации. Или вы можете использовать новый процесс, но в дополнение к этому код, который обрабатывает намерение com.google.android.c2dm.intent.REGISTRATION
, чтобы убедиться, что вы охвачены, если Google решит обновить идентификатор регистрации.
Тем не менее, я никогда не испытывал такого обновления, и даже когда у меня возникли изменения в идентификаторе регистрации (обычно в результате отправки уведомления после снятия установки с приложения, а затем его повторной установки), старый идентификатор регистрации все еще работал (в результате был зарегистрирован идентификатор регистрации в Google), поэтому никакого вреда не было.
EDIT (06.06.2013):
Google изменил свое Demo App для использования нового интерфейса. Они обновляют идентификатор регистрации, устанавливая дату истечения срока действия, сохраненное локально приложением. Когда приложение запускается, они загружают свой локально сохраненный идентификатор регистрации. Если он "истек" (который в демо означает, что он был получен от GCM более 7 дней назад), они снова вызывают 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;
}
EDIT (08.14.2013):
Google снова изменил свое Demo App (два дня назад). На этот раз они удалили логику, в которой идентификатор регистрации истекает через 7 дней. Теперь они обновляют только регистрационный идентификатор, когда новая версия установленного приложения.
EDIT (04.24.2014):
Для полноты, вот слова Costin Manolache (взяты из здесь), разработчика Google, участвующего в разработке GCM, по этому вопросу:
"Периодическое обновление" никогда не происходило, и обновление регистрации не входит в новую библиотеку GCM.
Единственной известной причиной изменения идентификатора регистрации является старая ошибка приложений автоматически получать незарегистрированные сообщения, если они получают сообщение в то время как обновляется. Пока эта ошибка не будет устранена, приложениям все равно необходимо позвонить register() после обновления, и до сих пор идентификатор регистрации может изменяться в Это дело. Вызов unregister() явно обычно изменяет Идентификатор регистрации.
Рекомендация/обходной путь - генерировать свой собственный случайный идентификатор, например, для сохранения в качестве общего предпочтения. При каждом обновлении приложения вы можете загрузить идентификатор и потенциально новый идентификатор регистрации. Эта может также помочь отслеживать и отлаживать обновление и регистрацию изменения на стороне сервера.
Это объясняет текущую реализацию официального демонстрационного приложения GCM.
com.google.android.c2dm.intent.REGISTRATION
никогда не должно обрабатываться при использовании класса GoogleCloudMessaging
для регистрации.