Cómo evitar el retraso en los mensajes de Android GCM / cambiar latido del corazón

He estado leyendo muchas publicaciones relacionadas con un problema de GCM que afecta a algunas personas. Parece que en algunos dispositivos / enrutadores / operadores las notificaciones sufren retrasos. He experimentado este problema con mi enrutador: los mensajes llegaron con mucha demora en WIFI, pero llegaron al instante cuando deshabilité WIFI y me conecté a la red móvil.

Parece que hay una solución que se puede hacer desde la aplicación de Android. Algo así como boost los latidos del corazón que mantienen viva la conexión GCM, más o menos.

¿Alguien puede decirnos qué debemos hacer para evitar el retraso? ¿Cómo podemos mantener la conexión con GCM desde una aplicación de Android? Un ejemplo de código (y dónde y cómo usarlo) sería realmente útil.

Esta publicación explica el problema. Dice que “podríamos mantener la conexión activa con un ping cada dos minutos desde el servidor GCM (que es gratis)”. ¿Cómo podemos hacer eso?

Muchas gracias


Las siguientes aplicaciones parecen hacer el truco. Sorprendentemente, el primero no necesita ningún permiso, la segunda conexión a Internet y el tercero solo para teléfonos rooteados:

https://play.google.com/store/apps/details?id=at.pansy.droid.gcmWifiFix

https://play.google.com/store/apps/details?id=com.elotro.pushheartbeat

https://play.google.com/store/apps/details?id=com.andqlimax.pushfixer

Me gustaría poner esto como un comentario en la primera respuesta, pero no tengo suficiente reputación.

Tuve un problema similar y lo resolví ejecutando el siguiente código antes de llamar a mi servicio web.

context.sendBroadcast(new Intent("com.google.android.intent.action.GTALK_HEARTBEAT")); context.sendBroadcast(new Intent("com.google.android.intent.action.MCS_HEARTBEAT")); 

Espero que te ayude!

No hay necesidad de enviar el latido del corazón del servidor GCM al teléfono, puede forzar a que el propio Android envíe el latido del corazón antes de lo que lo haría.

Eché un vistazo a la aplicación Push Notifications Fixer, que probé y funcionó para mí, y parece que todo lo que necesita hacer es transmitir los siguientes propósitos:

 com.google.android.intent.action.MCS_HEARTBEAT com.google.android.intent.action.GTALK_HEARTBEAT 

No estoy seguro de por qué está enviando ambos, puedes probar solo uno y ver si funciona bien. Aquí está el enlace a la aplicación (no soy el desarrollador): https://play.google.com/store/apps/details?id=com.andqlimax.pushfixer.noroot

Una solución alternativa si tiene permisos de raíz : puede verificar y cambiar los tiempos de latido de GCM manualmente. El valor predeterminado es 900000 (15 minutos). Configuré a 240000 (4 minutos) para estar seguro y evitar 5 minutos de tiempo de espera del enrutador.

Comprobar el tiempo del latido del corazón (shell)

 adb shell su sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "SELECT * FROM main WHERE name ='gtalk_max_server_heartbeat_time';" sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "SELECT * FROM main WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms';" 

Cambiar el tiempo del latido del corazón (shell)

 sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "UPDATE main SET value = '240000' WHERE name = 'gtalk_max_server_heartbeat_time' sqlite3 /data/data/com.google.android.gsf/databases/gservices.db "UPDATE main SET value = '240000' WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms' 

Cambiar el tiempo del latido (Android)

 Process proc = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(proc.getOutputStream()); os.writeBytes("sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \"UPDATE main SET value = '240000' WHERE name = 'gtalk_max_server_heartbeat_time'\"\n"); os.writeBytes("sqlite3 /data/data/com.google.android.gsf/databases/gservices.db \"UPDATE main SET value = '240000' WHERE name LIKE 'gtalk_%heartbeat_ping_interval_ms'\"\n"); os.writeBytes("exit\n"); os.writeBytes("exit\n"); os.flush(); os.close(); proc.waitFor(); 

"we could keep the connection alive with a ping every two minutes from the GCM server (which is free)". How can we do that?

Puede hacerlo enviando un mensaje GCM desde su servidor a todos los dispositivos en los que desea que se realice este ping. Puede colocar alguna carga especial en ese mensaje que la aplicación del dispositivo procesará de forma silenciosa (y no mostrará ninguna notificación). Sin embargo, dicho ping acortará la duración de la batería de los dispositivos que usan esta aplicación.

No se trata de cómo recibes el empuje, sino de cómo lo envías.

Puede establecer la prioridad del mensaje en “alto” (desde donde envía el push, su servidor)

https://developers.google.com/cloud-messaging/concept-options#setting-the-priority-of-a-message