77 votes

Gestion des modifications d'identifiant d'enregistrement dans Google Cloud Messaging sous Android

Dans les docs sur Google Cloud Messaging, il indique:

L'application Android devrait stocker ce code pour l'utiliser plus tard (pour exemple, pour vérifier onCreate() si elle est déjà enregistrée). Note que Google peut régulièrement à jour l'enregistrement de l'ID, de sorte que vous devez concevoir votre application Android avec la compréhension que l' com.google.android.c2dm.l'intention.ENREGISTREMENT intention peut être appelé à de multiples reprises. Votre Android l'application doit être en mesure de répondre en conséquence.

- Je enregistrer mon appareil à l'aide du code suivant:

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

Le GoogleCloudMessaging classe encapsule le processus d'inscription. Alors, comment suis-je supposé s'occuper des com.google.android.c2dm.l'intention.ENREGISTREMENT depuis la manipulation qui est faite en interne par le GoogleCloudMessaging classe?

137voto

Eran Points 35360

C'est une question intéressante.

Google vous encourager à passer à la nouvelle procédure d'immatriculation :

Une application Android en cours d'exécution sur un appareil mobile registres de recevoir des messages par l'appel de la GoogleCloudMessaging méthode register(senderID...). Cette méthode enregistre la demande de GCM et retourne l'IDENTIFIANT d'inscription. Cette approche simplifiée remplace la précédente GCM processus d'inscription.

La remarque que, dit - Google may periodically refresh the registration ID ne s'affiche que sur la page qui affiche toujours le vieux processus d'inscription, il est donc possible que cette remarque n'est plus pertinente.

Si vous voulez être sûr, vous pouvez toujours utiliser l'ancien processus d'inscription. Ou vous pouvez utiliser le nouveau processus, mais ils ont en plus le code qui gère l' com.google.android.c2dm.intent.REGISTRATION d'intention, afin de s'assurer que vous êtes couvert si Google décide à jour l'enregistrement de l'ID.

Cela dit, je n'ai jamais connu une telle actualisation, et même quand j'ai fait l'expérience d'un changement dans l'enregistrement de l'ID (généralement à la suite de l'envoi d'une notification après l'onu-l'installation de l'application, puis de le réinstaller), l'ancien enregistrement ID toujours travaillé (résultant en un canoniques de l'enregistrement de l'ID envoyé dans la réponse de Google), donc pas de mal a été fait.

EDIT (06.06.2013) :

Google a changé leur Démo App à utiliser la nouvelle interface. Ils actualisation de l'enregistrement de l'ID en paramètre une date d'expiration sur la valeur persisté localement par l'application. Lorsque l'application démarre, ils chargent leurs stockés localement id d'enregistrement. Si il est "périmé" (qui, dans la démo signifie qu'il a été reçu à partir de la GCM, de plus de 7 jours), ils l'appellent gcm.register(senderID) de nouveau.

Ce n'est pas la poignée du scénario hypothétique dans lequel un numéro d'enregistrement est actualisé par Google pour une application qui n'a pas été lancé pour un long moment. Dans ce cas, l'application ne sera pas au courant du changement, ni la 3ème partie serveur.

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 a changé leur Démo App de nouveau (il y a deux jours). Cette fois, ils ont enlevé la logique qui tient compte de l'IDENTIFIANT d'Inscription pour être expiré après 7 jours. Maintenant ils seulement l'actualisation de l'IDENTIFIANT d'Inscription lorsqu'une nouvelle version de l'application installée.

EDIT (04.24.2014) :

Par souci d'exhaustivité, voici les paroles de Costin Manolache (prises à partir d' ici), un Google developer impliqués dans le développement de la GCM, sur la question :

Le périodique' actualisation n'est jamais arrivé, et l'enregistrement d'actualisation n'est pas inclus dans la nouvelle GCM bibliothèque.

La seule cause connue pour l'enregistrement de l'ID de changement est le vieux bug d'applications se désinscrit automatiquement s'ils reçoivent un message alors obtenir mis à jour. Jusqu'à ce que ce bug est corrigé applications toujours besoin d'appeler register() après la mise à niveau, et la mesure de l'IDENTIFIANT d'inscription peuvent changer dans ce cas. L'appel de désinscription() explicitement habituellement des changements de la l'enregistrement de l'ID de trop.

La suggestion/solution de contournement consiste à générer votre propre identifiant aléatoire, enregistré partagé préférence pour l'exemple. Sur chaque application mise à niveau, vous pouvez télécharger l'identifiant et potentiellement de nouvelles ID d'enregistrement. Cette peut également aider à suivre et le débogage de la mise à niveau et de l'enregistrement les modifications sur le serveur de côté.

C'est ce qui explique l'actuelle mise en œuvre officielle de la GCM Démo de l'application. com.google.android.c2dm.intent.REGISTRATION ne devraient jamais être manipulés lors de l'utilisation de l' GoogleCloudMessaging classe pour vous inscrire.

2voto

rahulserver Points 1347

Après avoir passé en revue des tomes de réponses trompeuses sur le net, y compris SO, le SEUL endroit où j'ai trouvé une réponse complète était comme remarqué par la réponse d'Eran et ici :

Bien que l'actualisation de l'enregistrement automatique puisse ou ne se soit jamais produite, Google décrit un algorithme simple permettant de gérer les identificateurs canocical en analysant la réponse reçue:

 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.
 

De lien précité.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X