Android手机上消息推送的几种方式:

  1.轮询:应用程序应当阶段性的与服务器进行连接并查询是否有新的消息到达,你必须自己实现与服务器之间的通信,例如消息排队等。而且你还要考虑轮询的频率,如果太慢可能导致某些消息的延迟,如果太快,则会大量消耗网络带宽和电池。

  2.SMS即短信:在Android平台上,通过拦截SMS消息并且解析消息的内容来了解服务器的意图。可以实现完全的实时操作,但是成本相对较高,很难找到免费的短消息发送网关。

  3.持久连接:这种方案能解决由轮询带来的性能问题,但是还是会消耗手机的电池。但也存在着不足,就是我们很难在手机上实现一个可靠的服务。Android操作系统允许在低内存的情况下杀死系统服务。

  4.定期查询:按照指定的时间间隔连接服务器查询最新的消息。实现起来简单,非实时,查询时间过短则流量耗费多,耗电量大。

  5.C2DM:GOOGLE提供了消息的PUSH功能,需要和GOOGLE账号绑定。

  6.XMPP:在客户端集成asmack,服务器端使用ejabberd或openfire等开源的XMPP服务器软件也是一种可行的方式。缺点是先要有注册、登录等过程,无线环境下的连接效果不怎么样。重要消息的PUSH需要自己确认逻辑。

  7.MQTT:MQTT是一个轻量级的消息发布/订阅协议,它是基于手机客户端的消息推送服务器的理想解决方案。

下面是基于MQTT的简单实现方案:

服务器:

  可以采用IBM的MQTT服务器RSMB;

  开源的Mosquitto

客户端:

  IBM的wmqtt.jar适用于客户端。 

1.下载安装运行Mosquitto服务器

2.在android客户端集成一下代码:

import com.ibm.mqtt.IMqttClient;
import com.ibm.mqtt.MqttClient;
import com.ibm.mqtt.MqttException;
import com.ibm.mqtt.MqttPersistence;
import com.ibm.mqtt.MqttPersistenceException;
import com.ibm.mqtt.MqttSimpleCallback;

public class MQTTConnection implements MqttSimpleCallback{
    IMqttClient mqttClient = null;    
    private static int MQTT_PORT =1883; 
    private static MqttPersistence MQTT_PERSISTENCE=null;
    public static String MQTT_CLIENT_ID ="";
    private static boolean MQTT_CLEAN_START = true;
    private static short MQTT_KEEP_ALIVE = 60 * 15;
    private static int[] MQTT_QUALITIES_OF_SERVICE = { 0 } ;
    private long mStartTime;
        
    public MQTTConnection(String brokerHostName, String initTopic) throws MqttException {
        String mqttConnSpec = "tcp://" + brokerHostName + "@" + MQTT_PORT;
        // Create the client and connect
        mqttClient = MqttClient.createMqttClient(mqttConnSpec, MQTT_PERSISTENCE);
        String clientID = MQTT_CLIENT_ID;
        mqttClient.connect(clientID, MQTT_CLEAN_START, MQTT_KEEP_ALIVE);

        // register this client app has being able to receive messages
        mqttClient.registerSimpleHandler(this);
        
        // Subscribe to an initial topic, which is combination of client ID and device ID.
        subscribeToTopic(initTopic);

        // Save start time
        mStartTime = System.currentTimeMillis();
        // Star the keep-alives
        //startKeepAlives();            
    }
    
    private void subscribeToTopic(String topicName) throws MqttException {
        
        if ((mqttClient == null) || (mqttClient.isConnected() == false)) {
            // quick sanity check - don't try and subscribe if we don't have
            //  a connection
            System.out.println("subscribe to topic fail");
        } else {                                    
            String[] topics = { topicName };
            mqttClient.subscribe(topics, MQTT_QUALITIES_OF_SERVICE);
        }
    }    
    
    public void disconnect() {
        try {            
            mqttClient.disconnect();
        } catch (MqttPersistenceException e) {
            System.out.println("disconnection to server error");
        }
    }

    
    @Override
    public void connectionLost() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("connection to server closed");
    }

    @Override
    public void publishArrived(String topicName, byte[] payload, int qos, boolean retained)
            throws Exception {
        // TODO Auto-generated method stub
        String s = new String(payload);
        System.out.println("push message recived :"+s);
    }
}

3.运行客户端程序,在命令窗口中使用Mosquitto_pub.exe -q[QoS级别] -t[主题] -m[发布的内容] 进行测试。

另:Mosquitto由于使用socket select 模型,能支持的客户端连接数量有限。