How to Implement Push Notifications for Android

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 M

QTT 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.

Introduction

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 theAndroid Developer Labs.Obviously, 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 a pleasure. The SDK was easy to setup, easy to use and 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 performing 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. Obviously, 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:

  • Poll?The name obviously tells you that it’s really not even push. The idea here is to periodically poll the server for new messages from
    a background local or remote service. The more often you poll the closer you get to the real-time push.
Advantages:easy to implement. no cost solution Disadvantages:Obviously, you will never be actually real-time. If you polling interval is 30 min, you can get a message that is 29 minutes and 59 seconds late. Moreover, polling more often than every 15-30 min will kill your battery pretty quickly:https://labs.ericsson.com/apis/mobile-java-push/blog/save-device-battery-mobile-java-push
  • SMSAndroid allows you to intercept SMS messages. Your server sends a specially encoded SMS to your phone, whenever there is something new. Your app intercepts all messages, looks for the ones from the server, then pops up a notification.
Advantages:easy to implement. Fully real-time updates. Known drop-in solutions exist such as one provided byEricssonLabs:https://labs.ericsson.com/apis/mobile-java-push/ Disadvantages:Can be costly to you and the user. There are only a few services that allow you send around free SMS and even those are often limited to North America. If you want to have a reliable SMS-based service that is available worldwide, you will likely need to pay. Similar goes for the users. Not everyone has an SMS plan and you don’t want your users getting charged by 3rd party for using your app.
  • Persistent TCP/IPThe phone initiates a long-lived mostly idle TCP/IP connection with the server and maintains it byoccasionallysending keepalive messages. Whenever there is something new on the server, it sends a messages to the phone over the TCP connection.
Advantages: Fully real-time updates. Disadvantages: Hard to implement a reliable service on both the phone and the server side. The Android OS is known to be able to kill services when it’s running low on memory, so your notifications service can easilydisappear. What happens when your phone goes to sleep? Some people complain about battery life issues related to maintaining an active connection.

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, many developers out there agree that it is probably the best way to go until Google actually takes the matter in their own hands.

Persistent TCP/IP

After more Googling around I was able to comeacross threereasonableefforts to implement push notifications using a persistent TCP/IP connection:

  • Josh Guilfoyletalks about how to create a most-idle TCP/IP connection with a long keep-alive timer based on theAlarmManager. He provides some really cool sample code with a service that runs in the background and makes connections.http://devtcg.blogspot.com/2009/01/push-services-implementing-persistent.html
  • Dave Rearecently started the Deacon project, which is aimed at developing a 3rd party library for Android push notifications usingcomet technologybased onthe Meteor server. The project is still in a very early stage (at the time of this post), but looks quite promising.http://deacon.daverea.com/
  • Dale Lanehad done a number of presentations, where he talked about using the IBM developedMQTTprotocol for implementing Android push notifications. He also provides some really useful sample Android code.http://dalelane.co.uk/blog/?p=938

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’sTestKeepAliveproject and Dale Lane’s MQTT work. I borrow quite a bit of code from those guys, so they should get most of the credit. Anyways, enough for the introduction, let’s get to the good stuff.

My Idea

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 forMQ 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 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. In this case, each device can 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.

Architecture

In my example, Iutilizea PHP script as a server. This uses the SimpleAsynchronous Messaginglibrary (see project SAMhttp://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 diagram:

wmqtt.jaris a simple drop-in implementation of MQTT protocol provided by IBM. It can be downloaded fromhttp://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 IBMhttp://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 serverhttp://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 onlinehttp://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 notifications 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 onGitHub.

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 tohttp://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 should get a notification on your phone. It’s as easy as that.

You can see the source code forandoid-pushinthis GitHubproject. 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 could 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 othererroneous 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!

Anton Lopyrev

Follow me on twitter@tokudu

简要总结:

1)client端

作者给出了android上面的client端程序见:AndroidPushNotificationsDemo

2)server端

首先需要自己安装Mosquittohttp://mosquitto.org/download/, 在MQTT Wiki上可以找到更多关于API,关于如何使用MQTT的介绍。

3)发送消息

使用PHP发送消息的示例程序,见:PhpMQTTClient。

用上面给出的例子代码,就可以自己搭建一个环境进行测试。

上面就是对上面文章的简要总结。

上述步骤需要用PHP,然后搭建webserver来发送消息。但是,有时候我们并不方便搭建webserver,或者我们只想通过程序发消息,应该怎么办呢?可以用python脚本发送。

(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脚本发送消息的程序

可以考虑使用python。下面给出使用python的例子程序。(参见:http://mqtt.org/wiki/doku.php/python_examples)

我安装了python27,并且安装了Mosquitto目录下面python目录下面的库(python setup.py install)。

给出代码:

#!/usr/bin/env python
#
coding=utf-8


import mosquitto
import os
import time

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()
mqttc.publish("topic", msg)
print "message published"
time.sleep(1)
pass

在执行上面脚本时,会提示“TypeError: expected string or Unicode object, NoneType found”

解决方法:把mosquitto.dll所在目录加入path环境变量。参见:https://lists.launchpad.net/mqtt-users/msg00043.html

更多相关文章

  1. Android(安卓)环境搭建
  2. Android开发环境搭建
  3. 使用NetBeans搭建Android开发环境
  4. android ndk编译x264开源(用于android的ffmpeg中进行软编码)
  5. 第一章 andriod studio 安装与环境搭建
  6. Android(安卓)ROM的创建和烧录
  7. Android(安卓)ASE 脚本环境
  8. 工作环境搭建(8) - CentOS7命令行安装Android(安卓)SDK
  9. 搭建 android 代码镜像服务

随机推荐

  1. Android材料设计之材料主题
  2. 巧用Android图片资源,打造更精致的APP
  3. Android自定义视图三:给自定义视图添加“
  4. 【原创】Android 耗电信息统计服务——Ba
  5. android mms流播放器
  6. android 判断是否支持闪光灯
  7. Android中C/C++的日志打印
  8. OMS:拥有Android血统的智能操作系统王
  9. Android中的异步消息处理机制Hander
  10. Android上的Back键事件捕获