Обработка изменений идентификатора регистрации в Google Cloud Messaging на Android



в документах на Google Cloud Messaging он гласит:




приложение Android должно хранить этот идентификатор для последующего использования (для
например, чтобы проверить onCreate (), если он уже зарегистрирован). Отмечать
что Google может периодически обновлять идентификатор регистрации, так что вы
нужно разработать приложение для Android с пониманием того, что
com.гуглить.андроид.c2dm.намерение.Намерение регистрации может быть названо
несколько раз. Ваше приложение для Android должно иметь возможность отвечать
соответственно.




я регистрирую свое устройство, используя следующий код:



GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String regID = gcm.register(senderID);


класс GoogleCloudMessaging инкапсулирует процесс регистрации. Так как же я должен обращаться с com.гуглить.андроид.c2dm.намерение.Регистрация с момента обработки, которая выполняется внутренне классом GoogleCloudMessaging?

525   3  

3 ответов:

это интересный вопрос.

Google рекомендует вам перейти к новому процессу регистрации:

приложение Android, работающее на мобильном устройстве, регистрируется для получения сообщений путем вызова метода GoogleCloudMessaging register(senderID...). Этот метод регистрирует приложение для GCM и возвращает идентификатор регистрации. Этот упрощенный подход заменяет предыдущий процесс регистрации GCM.

записка, в которой говорится: Google may periodically refresh the registration ID появляется только на странице, которая все еще показывает старый процесс регистрации, поэтому возможно, что эта заметка больше не актуальна.

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

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

EDIT (06.06.2013):

Google изменил их Демо Приложения для использования нового интерфейса. Они обновляют идентификатор регистрации, устанавливая дату истечения срока действия на значение сохраняется локально приложением. При запуске приложения они загружают свой локально сохраненный идентификатор регистрации. Если он "истек" (что в демо означает, что он был получен от 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 изменил их Демо Приложения еще раз (два дня назад). На этот раз они удалили логику, которая считает, что срок действия регистрационного идентификатора истек через 7 дней. Теперь они обновляют только регистрационный идентификатор, когда установлена новая версия приложения.

EDIT (04.24.2014):

для полноты картины, вот слова Костина Манолаке (взято из здесь), разработчик Google, участвующий в разработке GCM, по этому вопросу:

"периодическое" обновление никогда не происходило, и обновление регистрации не входит в новую библиотеку GCM.

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

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

это объясняет текущая реализация официального демонстрационного приложения GCM. com.google.android.c2dm.intent.REGISTRATION никогда не следует обрабатывать при использовании GoogleCloudMessaging класс для регистрации.

читая новый API InstanceID, я нашел дополнительную информацию о том, когда токен может измениться:

ваше приложение может запрашивать токены из службы идентификаторов экземпляров по мере необходимости используя метод getToken (), и как InstanceID, ваше приложение также может храните токены на собственном сервере. Все маркеры, выпущенные на ваше приложение принадлежать получить идентификатор экземпляра приложения.

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

Подробнее:

служба идентификатора экземпляра периодически инициирует обратные вызовы (например, каждые 6 месяцев), запрашивая, чтобы ваше приложение обновляло свои токены. Это может быть также инициировать обратные вызовы, когда:

  • есть проблемы безопасности; например, проблемы SSL или платформы.
  • информация об устройстве больше не действует; например, резервное копирование и восстановление.
  • служба идентификатора экземпляра в противном случае влияет.

источники:

https://developers.google.com/instance-id/

https://developers.google.com/instance-id/guides/android-implementation

после очистки через тонны вводящих в заблуждение ответов по сети, в том числе так, единственное место, где я нашел полный ответ, было отмечено ответом Эрана и здесь:

в то время как автоматическое обновление регистрации может или никогда не происходило, google описывает алгоритм simiple для обработки canocical_ids путем анализа успешного ответа:

If the value of failure and canonical_ids is 0, it's not necessary to parse the remainder of the response. Otherwise, we recommend that you iterate through the results field and do the following for each object in that list:

If message_id is set, check for registration_id:
If registration_id is set, replace the original ID with the new value (canonical ID) in your server database. Note that the original ID is not part of the result, so you need to obtain it from the list of code>registration_ids passed in the request (using the same index).
Otherwise, get the value of error:
If it is Unavailable, you could retry to send it in another request.
If it is NotRegistered, you should remove the registration ID from your server database because the application was uninstalled from the device or it does not have a broadcast receiver configured to receive com.google.android.c2dm.intent.RECEIVE intents.
Otherwise, there is something wrong in the registration ID passed in the request; it is probably a non-recoverable error that will also require removing the registration from the server database. See Interpreting an error response for all possible error values.

из вышеупомянутой ссылки.

Comments

    Ничего не найдено.