Hello everyone. In this post I will try to provide you with a quick example on how to implement push notifications for your Android app using MQtt protocol. I will not discuss here why an application might need push notifications or the advantages of push over pull. I assume that you know exactly
What I mean by push notifications are and why you might need them. However, before jumping in straight to the good stuff, let's go over how it all started.
It's been around 4 months now since I 've started developing apps on the Android platform. it began with me scoring a free Nexus One phone at one of the android developer labs. obviusly, I couldn't resist trying to hack around with some code, so I downloaded the SDK and dove in. I guess in some sense, that's exactly what Google was hoping for when they starting giving out free phones. while it might sound like I got lucky, In the end Google is the one who won.
Anyway, developing for the Android platform turned out to the pleasure. the SDK was easy to setup, easy to use and easy to understand. putting together your first app was a breeze. I was very impressed.
Unfortunately, I soon realized that android is not perfect. one of the things that really disappointed me was the lack of a native method for processing Ming push notifications. over the past year push notifications became almost a standard in the mobile space thanks to Apple. even though BlackBerry utlilized push since God knows when, it was apple that really brought push mainstream. obviusly, lack of native push on Android seems like a huge
Drawback. naturally, I started looking around for a solution. after googling through dozens and dozens of blogs and message boards, I 've realized that there are 3 generally accepted ways to implement push notifications for your Android app. all of which are non-trivial, hacky and have their own disadvantages. let's go over the list:
The first two methods have significant disadvantages that we cannot do anything about. however, the third method's drawbacks are not as severe. it seems like with enough work and a good design, the persistent TCP/IP method can work. after all, that's how Gmail, Gtalk and Google Voice implement their real-time updates. in fact, please developers out there agree that it is probably the best way to go until Google actually takes the matter in their own hands.
After more googling around I was able to come into SS three reasonable efforts to implement push configurications using a persistent TCP/IP connection:
While all of the work done by these guys is incredible, none of their results are quite ready for drop-in use by other developers. in my effort to implement push notifications, I decided to put the pieces of the puzzle together and combine their results to produce a relatively stable way of implementing push. the example that I provide you with further, is a combination of Josh Guilfoyle's testkeepalive project and Dale Lane's mqtt work. I borrow quite a bit of code from those guys, so they shocould get most of the credit. anyways, enough for the introduction, let's get to the good stuff.
The problem with the testkeepalive project is that it creates a raw TCP connection, which means that you need write your own server to take care of push on the other side. while it's, without a question, doable, it is exactly why testkeepalive is far from a working solution. on the other hand, the mqtt example shown by Dale Lane uses the IBM's mqtt broker to handle the server work. to backup a little, mqtt stands for MQ telemetry transport, which is a protocol developed by IBM. let's take a quick look at the man page:
MqttIs 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 define 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 submit battery life related concerns about persistent TCP/IP connections. obviusly, 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. in this case, each device can be simply subscribe to a unique topic which is based on its device ID. now, assuming that your server knows the device ID, it can push data to the device over mqtt by publishing to that unique topic.
In my example, I utilize a PHP script as a server. this uses the simple asynchronous messaging Library (see project Sam http://project-sam.awardspace.com/) to publish mqtt messages to the broker on which I host on my server. let's have a look at the overall system digoal:
Wmqtt. JarIs a simple drop-in implementation of mqtt protocol provided by IBM. It can be downloaded from http://www-01.ibm.com/support/docview.wss? Rs = 171 & uid = swg24006006. the file that you download has a bunch of different stuff. Just look for the right jar file. You can include this jar as a part of your Android app.
Really small Message Broker (rsmb)Is a simple mqtt broker also provided by IBM http://www.alphaworks.ibm.com/tech/rsmb. it runs on port 1883 by default. in our architecture it accepts messages from the server and passes them on to the right devices. rsmb can also be replaced by the mosquitto server http://mosquitto.atchoo.org /.
SamIs a drop-in PHP library for mqtt and other stuff. You can either get it as PECL extension or download the source online http://pecl.php.net/package/sam/download/0.2.0.
Send_mqtt.phpIs a simple PHP script that accepts messages over post and uses Sam to pass-on messages to the broker.
Sample Code and demo
The goal of my work on push configurations was to develop a working demo, which is what all other examples out there lack. i'm happy to say that I accomplished my objective. you can download the sample Android app on GitHub.
This app (shown on the left) has a textview and two buttons. the textview contains your device ID and the buttons are used to start and stop the push notifications service. once you have the app on your phone, start the service. then go to http://tokudu.com/demo/android-push/ and enter the device ID in the first text box and enter the message text in the textarea below. press "send push message" and you shoshould get a notification on your phone. it's as easy as that.
You can see the source codeAndoid-pushInthis GitHub project. It contains the aforementionedSend_mqtt.phpScript.
If you didn't get a notification, make sure you have network connectivity. it can also be that the broker is down on my server (see server status on the page ). if that's the case, please post a comment and I will look into it bringing the broker back up.
Final thoughts and comments
Mqtt is definitely not the best way to implement push for Android, but it does work. one of the main drawbacks of mqtt is that anyone who knows the IP and the port at which the broker is running can connect and intercept your push messages. so it's probably a good idea to encrypt them. alternatively, you cocould write your own broker and introduce some sort of authentication to mqtt.
The code I provide here for the PUSH Service still needs more testing. reliability is definitely the main question. I think the code can definitely be improved to better handle connectivity loss and other erroneous situations. you are welcome to post your comments here regarding how it can be improved.
Also let me know if you find any bad bugs. Good luck testing!
Follow me on Twitter @ tokudu
The author provides the client program on Android as follows:Androidpushnotificationsdemo
2) server side
First you need to install mosquitto http://mosquitto.org/download/ yourself, on mqtt wiki you can find more about the API, about how to use mqtt.
3) send messages
For example programs that use PHP to send messages, see:Phpmqttclient.
With the sample code given above, you can build an environment for testing.
The above is a brief summary of the above article.
In the preceding steps, you need to use PHP and set up a webserver to send messages.However, what should we do if we do not set up a webserver easily or only want to send messages through a program? You can use a Python script to send messages.
(Above tutorials need setup Webserver, however, sometimes it is not so convenient for us to set up one web server and config corresponding environgments, we just need to send message to our android client, so I use python to solve this problem.A) install mosquitto.B) Write a Python script, send message to mosquitto, mosquitto will send message to Android client.)
4) Python scripts for sending messages
You can consider using python. The following is an example program using python. (See: http://mqtt.org/wiki/doku.php/python_examples)
I have installed Python 27 and installed the Library (Python setup. py install) under the python directory under the mosquitto directory ).
broker = "127.0.0.1"
port = 1883
mypid = os.getpid()
client_uniq = "pubclient_"+str(mypid)
mqttc = mosquitto.Mosquitto(client_uniq)
#connect to broker
mqttc.connect(broker, port, 60, True)
#remain connected and publish
while mqttc.loop() == 0:
msg = "test message "+time.ctime()
print "message published"
When executing the preceding script, the system prompts "typeerror: Expected string or Unicode object, nonetype found"
Solution: add the directory where mosquitto. dll is located to the PATH environment variable. See https://lists.launchpad.net/mqtt-users/msg00043.html