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 :
- Recuperar un número de teléfono con ContactsContract en Android: la función no funciona
- Cómo incluir la dependencia de JAR en una biblioteca AAR
- Necesidad de convertir AssetInputStream a FileInputStream
- Método Android con prioridad (paquete) visibilidad sobreestablecimiento (no debería funcionar, pero sí, ¿por qué?)
- Android: Dagger 2 y la inyección del constructor
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.
- ¿Qué significa usar un "." Sin un objeto en Android (o java)?
- SwitchPreference y CheckBoxPreference en el código
- Java - buscar host por dirección MAC
- ¿Hay alguna razón por la que no debería almacenar mi almacén de claves en el control de versiones?
- No se puede reloginar con las credenciales de Facebook después de cerrar la sesión
- Android GoogleMaps V2 MarkerDemo IllegalStateException no incluye puntos
- Cómo hacer http obtener solicitud en Android
- Android URLConnection.setRequestProperty () en android estudio no parece hacer nada
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: LosGCM 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 nuevoregistration ID
de Google. No necesito llamar al métodogcm.register()
nuevo en el listener Broadcast.
Espero que esto ayude a alguien a entender cómo manejar la renovación del ID de registro.
- ¿Cómo cambiar / restablecer el tiempo de retraso del controlador?
- Leer datos de un archivo de texto y mostrarlos en la vista de texto