Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Google Cloud Messaging: los mensajes no se reciben a veces hasta que se cambia el estado de la red

Mientras trabajaba en un pequeño proyecto que se integra con GCM, he tropezado con un poco de un extraño problema.

Algunas veces, cuando empiezo a ver el registro para ver si los mensajes se reciben, los mensajes no parecen estar llegando hasta que he cambiado el estado de la red (IE originalmente en WiFi, si apago WiFi y pasar a Mobile Data, los mensajes llegan multa). Después de que he cambiado el estado de la red, los mensajes comienzan a llegar perfectamente bien, y lo mismo se aplica una vez que cambie el estado de red de nuevo a lo que era antes (en este caso, WiFi) los mensajes siguen recibiendo.

El proyecto en sí incluye la capacidad de iniciar en arranque (inicia el GCMBaseIntentService en arranque), que funciona de nuevo perfectamente bien, y estoy seguro de que la aplicación / servicio se está ejecutando como he iniciado manualmente la aplicación cuando se produce este problema (que También comprueba si el servicio está en ejecución, y si no lo ejecuta y verifica si está registrado).

¿Alguien más se ha topado con este problema, o tiene alguna indicación de cómo podría resolver esto? No veo nada de mucha ayuda en el registro entre el tiempo en que los mensajes no se reciben y cuando están (después de cambiar el estado de la red). He pasado por los documentos de GCM y no puedo ver ninguna mención de mensajes que no se reciben debido a un tiempo de espera (en el dispositivo en sí), o cualquier configuración de opciones que puedan afectar a esto.

Apreciar cualquier ayuda – puedo proporcionar fuente si es necesario, aunque apenas se desvía de la aplicación de demostración proporcionada en el android-sdk.

  • Parse.com - Sonido personalizado de notificación push de Android
  • Google Cloud Messaging para Android Library no se encuentra en el administrador de sdk
  • FCM con AWS SNS
  • Error de autorización de GCM http 401
  • Mensajería de Google Cloud - Servidor de ejemplo
  • Obtenga el valor de RemoteMessage del método FCM onMessageReceived
  • Android L conflicto de permisos entre release y debug apks
  • Poll vs Push - ¿Alguna razón para evitar Push Notifications?
  • 5 Solutions collect form web for “Google Cloud Messaging: los mensajes no se reciben a veces hasta que se cambia el estado de la red”

    También he notado esto. Aunque no he cavado en el código real, aquí está mi comprensión de por qué sucede esto.

    GCM (y la mayoría de los servicios de mensajería push) funciona manteniendo un socket de larga duración abierto al servidor de notificación push de Google. El socket se mantiene abierto enviando mensajes "heartbeat" entre el teléfono y el servidor.

    Ocasionalmente, el estado de la red puede cambiar y este socket se rompe (porque la dirección IP del dispositivo cambia, de 3g a wifi, por ejemplo). Si el mensaje llega antes de restablecer el socket, el dispositivo no recibirá inmediatamente el mensaje.

    La reconexión sólo ocurre cuando el teléfono advierte que el socket está roto, lo que sólo ocurre cuando intenta enviar un mensaje de latido.

    Una vez más, sólo mi comprensión básica de cómo funciona y por qué sucede, y yo podría estar equivocado.

    Hay muchas causas para los retrasos de los mensajes GCM. Si el mensaje comienza a llegar después de que haya cambiado el estado de la red o haya activado o desactivado el modo avión, la causa más probable es una red que cierra la conexión sin enviar FIN / RST.

    GCM mantiene una conexión de larga duración – y se vuelve a conectar si sabe que la conexión se ha roto. Se supone que un enrutador / AP / NAT envía un FIN o RST para terminar la conexión TCP – por lo que GCM y los servidores sabrán que la conexión está muerta.

    Sin embargo, una serie de enrutadores y operadores móviles no lo hacen, y luego GCM necesita confiar en el latido del corazón, ~ 15 min en Wifi, más en el móvil. Hay un trade-off entre la duración de la batería / uso de la red y la frecuencia cardíaca.

    Según su comentario en la respuesta anterior y de acuerdo con mi experiencia con notificaciones push de GCM no hay ninguna razón de que si la red (conexión a Internet) está disponible no debe recibir notificaciones push Siempre comprobar la disponibilidad de conexión a Internet antes de ejecutar la aplicación de notificación push Como este intente comprobar esto si esto es verdad usted debe recibir notificaciones del empuje

    private boolean isNetworkAvailable() { ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null; } 

    Por lo tanto, si el pensamiento de @elfismike es cierto, puedo usar algo como:

      ConnectivityManager cm = (ConnectivityManager) context .getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); if (null != activeNetwork) { if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI) // here the network changed to Wifi so I can send a heartbeat to GCM to keep connection if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) //here the network changed to mobileData so I can send a heartbeat to GCM to keep connection } 

    Es mi solución buena?

    En la clase GCMIntentSevice, cuando recibe mensaje desde el servidor, onMessage método se llama así que en ese momento se puede hacer algo como …

     PowerManager pm = (PowerManager) getApplicationContext() .getSystemService(Context.POWER_SERVICE); WakeLock wakeLock = pm.newWakeLock( (PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP),"TAG"); wakeLock.acquire(); 

    Y tienes que agregar

    <uses-permission android:name="android.permission.WAKE_LOCK" /> permiso en el archivo de manifiesto.

    Esto debería funcionar…

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.