2013-06-27 7 views
5

Come la domanda dice che Come scoprire quando lo registration ID è diventato non valido nell'API GoogleCloudMessaging? Ho già letto le risposte su alcune domande su argomenti simili: Do GCM registration id's expire? e Google Coud Mesaging (GCM) and registration_id expiry, how will I know?. Il problema con queste domande è che le risposte ci sono per C2DM o la vecchia API GCM che utilizzava GCMRegistrar anziché l'API di GoogleCloudMessaging. I due metodi precedenti sono stati ammortizzati.Nell'API di GoogleCloudMessaging, come gestire il rinnovo o la scadenza dell'ID di registrazione?

Cercherò di rompere la mia confusione/domanda graduale:

1) Sotto il titolo Enable GCM, nel secondo punto si dice:

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) Ora, se questo è il caso it Dovrei gestire l'intento di un BroadcastReceiver e inviare nuovamente la richiesta register() per ottenere un nuovo ID di registrazione. Ma il problema è che nella stessa pagina sotto la voce ERROR_MAIN_THREAD, si dice che: GCM methods are blocking. You should not run them in the main thread or in broadcast receivers.

3) capisco anche che ci sono altri due scenari quando cambia ID di registrazione (come indicato sotto Argomenti avanzati nella rubrica Keeping the Registration State in Sync): aggiornamento Applicazione e Backup & ripristino. Li sto già gestendo all'apertura dell'app.

4) In GCMRegistrar API, all'interno GCMBaseIntentService, usato per essere un metodo di callback onRegistered(), che viene però chiamata quando il dispositivo fu registrata. Qui ero solito mantenere l'ID di registrazione e inviarlo a server di terze parti.

Ma, ora Come devo gestire l'aggiornamento o il rinnovo dell'ID di registrazione, persisterlo e inviarlo a server di terze parti?

Potrebbe essere che o mi sto confondendo leggendo tutto o mi manca qualcosa. Sarei davvero grato per il tuo aiuto.

Aggiornamento

Anche su Handling registration ID changes in Google Cloud Messaging on Android filo, non v'è alcuna menzione di come gestire il rinfresco periodico del Codice da parte di Google?

+0

Possibile duplicato di questo - http://stackoverflow.com/questions/16838654/handling-registration-id-changes-in-google-cloud-messaging-on-android/16839326#16839326 – Eran

risposta

4

sto dando un modo come quello che ho implementato nella mia applicazione

@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. 
} 

Si può fare in questo modo anche

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 

Ma il problema sorge quando, cancella utente i dati dell'applicazione e perderai l'attuale reg-id.


Aggiornamento per nuova API esempio Credits va a Eran e la sua risposta Handling registration ID changes in Google Cloud Messaging on Android

Google ha cambiato la loro Demo App di utilizzare la nuova interfaccia. Aggiornano l'ID di registrazione impostando una data di scadenza sul valore persistente localmente dall'app. All'avvio dell'app, caricano l'ID di registrazione memorizzato localmente. Se è "scaduto" (che nella demo significa che è stato ricevuto da GCM oltre 7 giorni fa), chiama di nuovo gcm.register(senderID).

Questo non gestisce l'ipotetico scenario in cui un ID di registrazione viene aggiornata da Google per un app che non è stato lanciato per un lungo periodo di tempo. In tal caso, l'app non sarà a conoscenza della modifica e nemmeno il server di terze parti.

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; 
} 
+0

Grazie per la risposta Pankaj. Lo hai fatto all'interno del servizio [GCMBaseIntentService] (http://developer.android.com/reference/com/google/android/gcm/GCMBaseIntentService.html)? Quando stavo usando [GCMRegistrar] (http://developer.android.com/reference/com/google/android/gcm/GCMRegistrar.html), ho usato questo servizio come hai fatto tu. –

+0

no no. Questo è il metodo di 'GCMIntentService'. –

+0

Oh Yaa .. scusa intendevo 'GCMIntentService' che estende' GCMBaseIntentService'? Questo è stato ammortizzato giusto? (Funziona ancora) –

0

solo per aggiungere alla risposta di Pankaj:

  • 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.

    E 'vero che l'esempio a Getting started documentazione non gestisce questo caso. Quindi lo sviluppatore ha bisogno di gestirsi da solo.

  • anche la risposta dice che 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.

    Il problema è che i sette giorni di scadenza locale del registration ID nel campione è quello di evitare lo scenario in cui il dispositivo invia la registrazione al server di terze parti, ma il server lo perde. Lo standard non gestisce l'aggiornamento dell'ID dai server di Google.

  • Il secondo punto sotto il titolo Enable GCM sulla Architectural Overview pagina, dice:

    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.

    Così, per la gestione che si dovrebbe avere una trasmissione Listener che in grado di gestire com.google.android.c2dm.intent.REGISTRATION intento, che Google invia all'app quando deve aggiornare l'ID di registrazione .

  • C'è un'altra parte della domanda in cui si afferma su the problem is that inside the Broadcast Listener I cannot call register the for Push ID again. This is because the documentation dice: GCM methods are blocking. You should not run them in the main thread or in broadcast receiver.

    penso che problema è completamente diverso da quello comunicato. Quando si registra un ricevitore di trasmissione, questo avrà un Intent che conterrà il nuovo registration ID da Google. Non è necessario chiamare di nuovo il metodo gcm.register() nel listener Broadcast.

Spero che questo aiuti qualcuno a capire come gestire il rinnovo dell'ID di registrazione.

+0

E 'una umile richiesta che se sei giù votando la risposta, si prega di commentare per spiegare ulteriormente. Questo mi aiuterà a migliorare la risposta e mi farà capire le tue opinioni sul contenuto della risposta. Sebbene la risposta precedente abbia aiutato ma in realtà non ha risposto/risolve la confusione, così ho risposto di nuovo. Se pensi che ci siano delle critiche nella risposta, ti prego di parlare. Cancellerà più concetti. Grazie ancora! –

+1

Non sono sicuro del motivo per cui questo è stato downvoted. È molto chiaro e utile Voto positivo da parte mia – KyleT

+0

qualsiasi cosa tu abbia scritto non risponde alla domanda e sei confuso tra vecchia e nuova API. sarebbe stato usato vecchio o sarebbe stato utilizzato nuovo –

Problemi correlati