En la API de GoogleCloudMessaging, ¿cómo manejar la renovación o caducidad del ID de registro?

Como la pregunta dice que ¿Cómo saber cuándo el ID de registro se ha convertido en inválido en GoogleCloudMessaging API? Ya he leído las respuestas en algunas preguntas sobre un tema similar: ¿El ID de registro de GCM expira? Y Google Coud Mesaging (GCM) y registration_id caducidad, ¿cómo lo sabré? . El problema con esas preguntas es que las respuestas son para C2DM o GCM antiguo API que utiliza GCMRegistrar en lugar de GoogleCloudMessaging API. Los dos métodos anteriores se han depreciado.

Voy a tratar de romper mi confusión / pregunta paso a paso :

1) Bajo el encabezado Habilitar GCM , en el segundo punto 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) Ahora, si ese es el caso, entonces debería manejar la intención en un BroadcastReceiver y enviar la solicitud register () de nuevo para obtener un nuevo ID de registro. Pero el problema es que en la misma página bajo el encabezado ERROR_MAIN_THREAD , se dice que: Los 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) También entiendo que existen otros dos escenarios cuando cambia el ID de registro (como se menciona en Temas avanzados bajo encabezado Mantener el estado de registro en sincronización ): Actualización de la aplicación y Copia de seguridad y restauración. Ya los estoy manejando al abrir la aplicación.

4) En GCMRegistrar API, dentro de GCMBaseIntentService , solía haber un método onRegistered () callback, que se llamó cuando el dispositivo se registró. Aquí he utilizado para persistir el registro de identificación y enviar a los servidores de terceros.

Pero, ahora ¿Cómo debo manejar la actualización o renovación del ID de registro, persistir y enviarlo al servidor de terceros?

Puede ser que me estoy confundiendo al leerlo todo o me falta algo. Estaría muy agradecido por su ayuda.

Actualizar

Incluso en el manejo de los cambios de ID de registro en Google Cloud Messaging en el subproceso de Android , no se menciona cómo manejar la actualización periódica de ID de Google.

Estoy dando una manera como lo que implementé en mi aplicación

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

Puedes hacer esto también

 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 

Pero el problema surge cuando, el usuario borra los datos de la aplicación y perderá el reg-id actual.


Actualización para el nuevo ejemplo de la API Créditos para Eran y su respuesta Manejo de los cambios en el ID de registro en Google Cloud Messaging en Android

Google cambió su aplicación de demostración para usar la nueva interfaz. Actualizan el ID de registro estableciendo una fecha de caducidad en el valor que la aplicación mantiene localmente. Cuando se inicia la aplicación, cargan su ID de registro almacenado localmente. Si está "caducado" (lo que en la demo significa que fue recibido de GCM hace más de 7 días), llaman gcm.register(senderID) nuevo.

Esto no maneja el hipotético escenario en el que un ID de registro es actualizado por Google para una aplicación que no se ha iniciado durante mucho tiempo. En ese caso, la aplicación no será consciente del cambio, y tampoco el servidor de terceros.

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

Sólo para añadir a la respuesta de 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.

    Es cierto que el ejemplo de la documentación de Getting Started no maneja ese caso. Así que el desarrollador necesita manejarse a sí mismo.

  • También la respuesta dice que 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.

    El problema es que la expiración local de siete días del registration ID en la muestra es evitar el escenario en el que el dispositivo envía el registro al servidor de terceros pero el servidor lo pierde. No controla la actualización de la ID de los servidores de Google.

  • El segundo punto en el encabezado Enable GCM en la página de vista general de arquitectura , 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.

    Por lo tanto, para el manejo que debe tener un Broadcast Listener que podría manejar com.google.android.c2dm.intent.REGISTRATION intención, que Google envía a la aplicación cuando tiene que actualizar el ID de registro.

  • Hay otra parte de la pregunta que los estados sobre 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 documentación dice: Los 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 .

    Creo que la cuestión es completamente diferente de la declaración. Cuando registre un receptor de difusión, tendrá un Intent que contendrá el nuevo registration ID de Google. No necesito llamar al método gcm.register() nuevo en el listener Broadcast.

Espero que esto ayude a alguien a entender cómo manejar la renovación del ID de registro.

  • ListView y Tabwidget en Fragmento
  • VerifyError con PowerMock en Android
  • Android - ¿Es mala práctica tener múltiples preferencias compartidas?
  • Android Spinner no funciona en dispositivos Samsung con Android 5.0
  • Cómo hacer que SearchView pierda el foco y se contraiga al hacer clic en otra parte de la actividad
  • Android: descarga de la imagen desde la Web, guardando en la memoria interna en una ubicación privada a la aplicación, mostrando para el elemento de lista
  • Cómo hacer que el arranque del emulador de Android sea más rápido
  • Html.ImageGetter TextView
  • ¿Cómo puedo crear un widget de aplicación de paginación de Android compatible con versiones anteriores?
  • Cambiar la actividad con Swipe
  • Java Lang UnsupportedClassVersion Error en Xamarin Studio
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.