Thursday, July 7, 2011

Android push notifications (tutorial)

Perhaps the most important feature of our server monitoring iPhone and Android apps is the ability to receive alerts via push notification directly to your device.
On the iPhone, notifications are easy to implement and included since iPhone OS 3 but on Android it’s a little more complex, and the Google provided “Android Cloud to Device Messaging” is only built into the OS as of Android 2.2. That said, it’s not just designed to send a simple message as it can include any kind of payload and used for any kind of updates, not just text alerts:
Android Cloud to Device Messaging (C2DM) is a service that helps developers send data from servers to their applications on Android devices. The service provides a simple, lightweight mechanism that servers can use to tell mobile applications to contact the server directly, to fetch updated application or user data. The C2DM service handles all aspects of queueing of messages and delivery to the target application running on the target device.
But since we wanted to support Android 1.6+ (1.6 and 2.1 making up 56.8% of deployed versions) then we needed an alternative to C2DM.
C2DM Alternatives
blog post on was amongst the top results in Google and provides a detailed walkthrough of the various options.
  • Polling. The application itself would periodically poll your servers to check for new messages. You would need to implement everything from queing messages to writing the polling code. Alerts are no good if they’re delayed due to a low polling period but the more frequently you poll, the more the battery is going to die.
  • SMS. Android can intercept SMS messages and you could include a payload to tell the app what to do. But then why not just use SMS in the first place?
  • Persistent connection. This would solve the problem of periodic polling but would destroy the battery life. Apple’s push notifications work well because there’s only ever 1 service connecting to Apple’s servers. This is also how the C2DM service works and means you don’t have every app leaving open connections.
A solution is proposed based on the persistent connection idea:
mqtt is a publish/subscribe messaging protocol intended that is designed to be lightweight. It is useful for use with low power sensors, but is applicable to many scenarios…Did you see the part about ‘low power’? So did I. Basically, the reason why one might consider using MQTT is that it was designed to be very lightweight, so that it doesn’t consume much power. This is ideal for a mobile push solution as it addresses many battery life related concerns about persistent TCP/IP connections. Obviously, MQTT also has some disadvantages such as privacy, but we can talk about that later. So, my idea consists of taking a KeepAliveService and replacing the raw TCP/IP connection with an MQTT connection.
This is a fairly nice solution, and Java sample code is provided, along with the PHP server side code. Yet it still suffers from a few key problems which stopped us from using it:
mqtt Diagram
  • Your app still has to maintain an open connection and that uses up a lot of battery if other apps are doing the same.
  • It requires the app to maintain connections to your servers on a custom port with a custom server. This makes it difficult to load balance and scale. It also requires opening a custom port and handling that kind of traffic. Our service currently operates entirely over HTTP/HTTPS and we like it that way. Communication with custom services like Apple is outgoing only.
  • The protocol is open by default. This means “anyone who knows the IP and the PORT at which the broker is running can connect and intercept your Push messages”, unless you write your own authentication.
There is an open source project being developed to create a proper client/server solution so you can run your own push service. But with that service not yet finished and considering these points, we decided to go for a different solution.

No comments:

Post a Comment