I\'ve setup an Android app with GCM support, and have a little test app to send a msg to the app. When I run the App in the emulator, I can see (via logging msgs) that it re
You cannot guarantee fast delivery because GCM to device connectivity may be poor as CommonsWare has pointed out. There are however, two possible delays in the delivery train: 1) GCM connecting to the phone (as mentioned previously) and 2) The delay in the message actually being sent out from the GCM server. If you set the 'time_to_live' parameter to 0 seconds in your sending application, then you can at least test where the delay is occurring.
A value of 0 seconds means that the message will be sent immediately and if delivery is unsuccessful, the message will be discarded on the GCM server. It is not a practical value for real life use, but will enable you to find out which part of the delivery train is causing the delay.
GCM is reportedly having a pretty severe problem with keep-alive heartbeat not being so reliable. Therefore, since it's only dispatched once every 15 minutes (over 3G) or 28 minutes (over Wifi), if for some reason the server connection is dropped, it may not be restored for several long minutes.
These type of shenanigans prompted developing a solution that does not rely on a 3rd-party network to deliver massively-scalable and reliable push notifications to offline (backgrounded) Android apps.
https://help.pubnub.com/entries/21720011-Can-my-Android-App-Receive-Messages-While-Inactive
This matter is important to me.
I have set up this code inside a one second timer Handler to send out a GCM message every 2 minutes. The hope is that it will keep things alive
if ((mOneSecondTick %120) == 0){
// q 1 minute check when we got last call....
long lDiff = System.currentTimeMillis() - GCMlastCall;
if (PushAndroidActivity.GCMAvailable){
Log.d("pushAndroidActivity",String.format("(mOneSecondTick %d",lDiff));
if (lDiff > 122 * 1000){ // more than a minute
Intent intent = new Intent(StayInTouch.this,PushAndroidActivity.class);
2startActivity(intent);
}else{ // every 2 minutes send out a gcm message...
asyncWebCall(String.format(AgeingLib.GCMTICKLE,androidid),0);
return; // only if it sends a tickle and all is well...
}
}else{
Log.d("pushAndroidActivity",String.format("(mOneSecondTick mod60 no GCM on this device"));
}
}
GCMlastCall is the last time a message was received, so we can tell if gcm stopped.
Been working for a couple of days now seems OK
We had the same problem, but it varied from network-to-network. We think it was the home hub router (a Virgin Super Hub) dropping the connection after five minutes of inactivity. You can confirm by sending an empty GCM message every two minutes to keep the connection alive.
Here is a more in-depth explanation of what we did: https://groups.google.com/d/msg/android-gcm/Y33c9ib54jY/YxnCkaPRHRQJ
This is indeed caused by unrealistic heartbeat intervals in Google Cloud Messaging.
This is possibly the most frustrating bug in GCM. GCM works by maintaining an idle socket connection from an Android device to Google’s servers. This is great because it barely consumes battery power (contrary to polling), and it allows the device to be woken up instantly when a message arrives. To make sure that the connection remains active, Android will send a heartbeat every 28 minutes on mobile connection and every 15 minutes on WiFi. If the heartbeat failed, the connection has been terminated, and GCM will re-establish it and attempt to retrieve any pending push notifications. The higher the heartbeat interval, the less battery consumed and the less times the device has to be woken up from sleep.
However, this comes at a great price: the longer the heartbeat interval, the longer it takes to identify a broken socket connection. Google has not tested these intervals in real-life situations thoroughly enough before deploying GCM. The problem with these intervals is caused by network routers and mobile carriers, who disconnect idle socket connections after a few minutes of inactivity. Usually, this is more common with cheap home routers, whose manufacturers decided on a maximum lifespan of an idle socket connection, and terminate it to save resources. These routers can only handle a finite number of concurrent connections, and so this measure is taken to prevent overload. This results in terminated GCM sockets, and when the time comes to deliver a GCM message, it does not reach the device. The device will only realize that the connection has been broken when it’s time to send a heartbeat, 0 – 28 minutes later, rendering the push notification useless in some situations (when the message is time-critical, for example). In my experience, most cheap routers terminate idle connections after about 5 – 10 minutes of inactivity.
I wrote an entire post about this and other GCM issues:
http://eladnava.com/google-cloud-messaging-extremely-unreliable/
An Alternative to Google Cloud Messaging
Pushy (https://pushy.me/) is a standalone push notification gateway, completely independent of GCM. It maintains its own background socket connection, just like GCM, to receive push notifications. The underlying protocol is MQTT, an extremely light-weight pub/sub protocol, utilizing very little network bandwidth and battery.
A huge advantage of Pushy is that the code for sending a push notification (from the server), and registering the device for push notifications, is actually interchangeable between GCM and Pushy. This makes it super easy to switch to Pushy after implementing GCM and having to ditch it for its instability.
(Full disclosure: I founded Pushy for my own projects and realized many apps would benefit from such a service)