ActiveMQ+MQTT协议 实现Android推送(根据订阅主题可实现点对点、集群推送)


最近功能要做一个推送的功能,在不用第三方推送的前提下,考虑了 MQTT协议实现推送,听说它的效率比RabbitMQ高一些,参考了网上的代码,总结一下,谢了一个demo

服务端我用的是java代码实现的

我的服务器版本是 apache-activemq-5.14.1


[java]  view plain  copy
  1. public class MqttBroker {  
  2.    
  3.         /**  
  4.          * 发送消息  
  5.          *   
  6.          * @param clientId   客户端主题 不是id 
  7.          * @param messageId  
  8.          */   
  9.         public void sendMessage(String clientId, String message) {    
  10.               
  11.             try {    
  12. //              mqttClient = new MqttClient(CONNECTION_STRING);  
  13.                 if (mqttClient == null || !mqttClient.isConnected()) {    
  14.                     connect();    
  15.                 }    
  16.                 System.out.println("send message to  + clientId + , message is "    
  17.                         + message);    
  18.                 // 发布自己的消息    
  19.                 mqttClient.publish(clientId, message.getBytes(),    
  20.                         0false);    
  21.                 /*mqttClient.publish(GMCC/tokudu/ + clientId, message.getBytes(),   
  22.                         0, false); */  
  23.               System.out.println( " #####################" + CLIENT_ID);    
  24.             } catch (MqttException e) {    
  25.                 e.printStackTrace();    
  26.             }    
  27.         }    
  28.    
  29.         /**  
  30.          * 简单回调函数,处理server接收到的主题消息  
  31.          *   
  32.          * @author Join  
  33.          *   
  34.          */   
  35.         class SimpleCallbackHandler implements MqttSimpleCallback {    
  36.    
  37.             /**  
  38.              * 当客户机和broker意外断开时触发 可以再此处理重新订阅  
  39.              */   
  40.             public void connectionLost() throws Exception {    
  41.                 // TODO Auto-generated method stub    
  42.                 System.out.println("客户机和broker已经断开");    
  43.             }    
  44.    
  45.             /** 和broker已 
  46.              * 客户端订阅消息后,该方法负责回调接收处理消息  
  47.              */   
  48.             public void publishArrived(String topicName, byte[] payload, int Qos,    
  49.                     boolean retained) throws Exception {    
  50.                 // TODO Auto-generated method stub    
  51.                 System.out.println("订阅主题:"  + topicName);    
  52.                 System.out.println("消息数据:"  + new String(payload));    
  53.                 System.out.println("消息级别(0,1,2):"  + Qos);    
  54.                 System.out.println("是否是实时发送的消息(false=实时,true=服务器上保留的最后消息): "    
  55.                         + retained);    
  56.             }    
  57.    
  58.         }    
  59.    
  60.         public static void main(String[] args) {    
  61.             new MqttBroker().sendMessage("90","this is my message");    
  62.         }  // 用反斜杠  不要用点  
  63.     }   

 Android客户端代码


[java]  view plain  copy
  1. package com.mst.v2.activity;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.Arrays;  
  5. import java.util.List;  
  6.   
  7. import com.ibm.mqtt.IMqttClient;  
  8. import com.ibm.mqtt.MqttClient;  
  9. import com.ibm.mqtt.MqttException;  
  10. import com.ibm.mqtt.MqttPersistence;  
  11. import com.ibm.mqtt.MqttPersistenceException;  
  12. import com.ibm.mqtt.MqttSimpleCallback;  
  13. import com.mst.v2.bean.MessageItem;  
  14. import com.mst.v2.db.MessageDbManager;  
  15. import com.mst.v2.util.MessageDailog;  
  16. import com.mst.v2.util.MyNotification;  
  17.   
  18. import android.app.AlarmManager;  
  19. import android.app.Notification;  
  20. import android.app.NotificationManager;  
  21. import android.app.PendingIntent;  
  22. import android.app.Service;  
  23. import android.content.BroadcastReceiver;  
  24. import android.content.ComponentName;  
  25. import android.content.Context;  
  26. import android.content.Intent;  
  27. import android.content.IntentFilter;  
  28. import android.content.ServiceConnection;  
  29. import android.content.SharedPreferences;  
  30. import android.media.MediaPlayer;  
  31. import android.net.ConnectivityManager;  
  32. import android.net.NetworkInfo;  
  33. import android.os.Binder;  
  34. import android.os.Bundle;  
  35. import android.os.Handler;  
  36. import android.os.IBinder;  
  37. import android.os.Message;  
  38. import android.util.Log;  
  39. import android.widget.Toast;  
  40.   
  41. import com.mst.v2.R;  
  42. import com.thunisoft.mst.shortcutbadger.ShortcutBadger;  
  43.   
  44. /*  
  45.  * PushService that does all of the work. 
  46.  * Most of the logic is borrowed from KeepAliveService. 
  47.  * http://code.google.com/p/android-random/source/browse/trunk/TestKeepAlive/src/org/devtcg/demo/keepalive/KeepAliveService.java?r=219 
  48.  */  
  49. public class PushService extends Service {  
  50.     // this is the log tag  
  51.     public static final String TAG = "MQTTPushService";  
  52.     public static final String BROKER_URL = "tcp://172.16.19.43:1883";  
  53.     private MyState sta = MyState.getInstance();  
  54.     // the IP address, where your MQTT broker is running.  
  55.     private static final String MQTT_HOST = "172.16.19.43";//MyState.getInstance().ucmIp ; ;  
  56.     // the port at which the broker is running.  
  57.     private static int MQTT_BROKER_PORT_NUM = 1883;  
  58.     // Let's not use the MQTT persistence.  
  59.     private static MqttPersistence MQTT_PERSISTENCE = null;  
  60.     // We don't need to remember any state between the connections, so we use a  
  61.     // clean start.  
  62.     private static boolean MQTT_CLEAN_START = true;  
  63.     // Let's set the internal keep alive for MQTT to 15 mins. I haven't tested  
  64.     // this value much. It could probably be increased.  
  65.     private static short MQTT_KEEP_ALIVE = 5 * 60;// 60 * 15  
  66.     // Set quality of services to 0 (at most once delivery), since we don't want  
  67.     // push notifications  
  68.     // arrive more than once. However, this means that some messages might get  
  69.     // lost (delivery is not guaranteed)  
  70.     private static int[] MQTT_QUALITIES_OF_SERVICE = { 0 };  
  71.     private static int MQTT_QUALITY_OF_SERVICE = 0;  
  72.     // The broker should not retain any messages.  
  73.     private static boolean MQTT_RETAINED_PUBLISH = false;  
  74.   
  75.     // MQTT client ID, which is given the broker. In this example, I also use  
  76.     // this for the topic header.  
  77.     // You can use this to run push notifications for multiple apps with one  
  78.     // MQTT broker.  
  79.     public static String MQTT_CLIENT_ID = "mtClient";  
  80.   
  81.     // These are the actions for the service (name are descriptive enough)  
  82.     private static final String ACTION_START = MQTT_CLIENT_ID + ".START";  
  83.     private static final String ACTION_STOP = MQTT_CLIENT_ID + ".STOP";  
  84.     private static final String ACTION_KEEPALIVE = MQTT_CLIENT_ID  
  85.             + ".KEEP_ALIVE";  
  86.     private static final String ACTION_RECONNECT = MQTT_CLIENT_ID  
  87.             + ".RECONNECT";  
  88.   
  89.     // Connection log for the push service. Good for debugging.  
  90.   
  91.     // Connectivity manager to determining, when the phone loses connection  
  92.     private ConnectivityManager mConnMan;  
  93.     // Notification manager to displaying arrived push notifications  
  94.     private NotificationManager mNotifMan;  
  95.   
  96.     // Whether or not the service has been started.  
  97.     private boolean mStarted;  
  98.   
  99.     // This the application level keep-alive interval, that is used by the  
  100.     // AlarmManager  
  101.     // to keep the connection active, even when the device goes to sleep.  
  102.     private static final long KEEP_ALIVE_INTERVAL = 1000 * 60 * 6;// 1000 * 60 *  
  103.                                                                     // 28  
  104.   
  105.     // Retry intervals, when the connection is lost.  
  106.     private static final long INITIAL_RETRY_INTERVAL = 1000 * 10;  
  107.     private static final long MAXIMUM_RETRY_INTERVAL = 1000 * 60 * 8;// 1000 *  
  108.                                                                         // 60 *  
  109.                                                                         // 30  
  110.   
  111.     // Preferences instance  
  112.     private SharedPreferences mPrefs;  
  113.     // We store in the preferences, whether or not the service has been started  
  114.     public static final String PREF_STARTED = "isStarted";  
  115.     // We also store the deviceID (target)  
  116.     public static final String PREF_DEVICE_ID = "deviceID";  
  117.     // We store the last retry interval  
  118.     public static final String PREF_RETRY = "retryInterval";  
  119.   
  120.     // Notification title  
  121.     public static String NOTIF_TITLE = "Tokudu";  
  122.     // Notification id  
  123.     private static final int NOTIF_CONNECTED = 0;  
  124.   
  125.     // This is the instance of an MQTT connection.  
  126.     private MQTTConnection mConnection;  
  127.     private long mStartTime;  
  128.     private Context mContext;  
  129.     MessageDbManager dbManager;  
  130.     public static int msgNumber = 0;// 服务器推送消息的数量  
  131.   
  132.     static PushService myService;  
  133.   
  134.     // Static method to start the service  
  135.     public static void actionStart(Context ctx) {  
  136.         Intent i = new Intent(ctx, PushService.class);  
  137.         // i.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK );  
  138.         i.setAction(ACTION_START);  
  139.         ctx.startService(i);  
  140.         // ctx.bindService(i, connection, BIND_AUTO_CREATE);  
  141.     }  
  142.   
  143.     // Static method to stop the service  
  144.     public static void actionStop(Context ctx) {  
  145.         Intent i = new Intent(ctx, PushService.class);  
  146.         i.setAction(ACTION_STOP);  
  147.         ctx.startService(i);  
  148.     }  
  149.   
  150.     // Static method to send a keep alive message  
  151.     public static void actionPing(Context ctx) {  
  152.         Intent i = new Intent(ctx, PushService.class);  
  153.         i.setAction(ACTION_KEEPALIVE);  
  154.         ctx.startService(i);  
  155.     }  
  156.   
  157.     @Override  
  158.     public void onCreate() {  
  159.         super.onCreate();  
  160.   
  161.         Log.i(TAG, "onCreate, creating service...");  
  162.         mStartTime = System.currentTimeMillis();  
  163.   
  164.         // Get instances of preferences, connectivity manager and notification  
  165.         // manager  
  166.         mPrefs = getSharedPreferences(TAG, MODE_PRIVATE);  
  167.         mConnMan = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);  
  168.         mNotifMan = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);  
  169.   
  170.         /* 
  171.          * If our process was reaped by the system for any reason we need to 
  172.          * restore our state with merely a call to onCreate. We record the last 
  173.          * "started" value and restore it here if necessary. 
  174.          */  
  175.         handleCrashedService();  
  176.   
  177.         mContext = this;  
  178.         dbManager = new MessageDbManager(mContext);  
  179.     }  
  180.   
  181.     // This method does any necessary clean-up need in case the server has been  
  182.     // destroyed by the system  
  183.     // and then restarted  
  184.     private void handleCrashedService() {  
  185.         if (wasStarted() == true) {  
  186.             Log.i(TAG, "Handle crashed service");  
  187.             // stop the keep alives  
  188.             stopKeepAlives();  
  189.             // Do a clean start  
  190.             startService();  
  191.         }  
  192.     }  
  193.   
  194.     @Override  
  195.     public void onDestroy() {  
  196.         Log.i(TAG, "onDestroy, Service started: " + mStarted);  
  197.         // Stop the services, if it has been started  
  198.         if (mStarted == true) {  
  199.             stop();  
  200.         }  
  201.     }  
  202.   
  203.     @Override  
  204.     public void onStart(Intent intent, int startId) {  
  205.         super.onStart(intent, startId);  
  206.         Log.i(TAG, "onStart, Service started with intent: " + intent);  
  207.         if (intent == null) {  
  208.             Log.e(TAG, "onStart intent = null");  
  209.             return;  
  210.         }  
  211.   
  212.         // Do an appropriate action based on the intent.  
  213.         if (intent.getAction().equals(ACTION_STOP) == true) {  
  214.             stop();  
  215.             stopSelf();  
  216.         } else if (intent.getAction().equals(ACTION_START) == true) {  
  217.             new Thread() {  
  218.                 @Override  
  219.                 public void run() {  
  220.                     // TODO Auto-generated method stub  
  221.                     super.run();  
  222.                     startService();  
  223.                 }  
  224.             }.start();  
  225.         } else if (intent.getAction().equals(ACTION_KEEPALIVE) == true) {  
  226.             keepAlive();  
  227.         } else if (intent.getAction().equals(ACTION_RECONNECT) == true) {  
  228.             if (isNetworkAvailable()) {  
  229.                 // if (mConnection == null)  
  230.                 reconnectIfNecessary();  
  231.             }  
  232.         }  
  233.     }  
  234.   
  235.     @Override  
  236.     public IBinder onBind(Intent intent) {  
  237.         return null;  
  238.     }  
  239.   
  240.     public class MyBinder extends Binder {  
  241.         PushService getService() {  
  242.             return PushService.this;  
  243.         }  
  244.     }  
  245.   
  246.     // Reads whether or not the service has been started from the preferences  
  247.     private boolean wasStarted() {  
  248.         return mPrefs.getBoolean(PREF_STARTED, false);  
  249.     }  
  250.   
  251.     // Sets whether or not the services has been started in the preferences.  
  252.     private void setStarted(boolean started) {  
  253.         mPrefs.edit().putBoolean(PREF_STARTED, started).commit();  
  254.         mStarted = started;  
  255.     }  
  256.   
  257.     private synchronized void startService() {  
  258.         Log.e(TAG, "startService, Starting...");  
  259.         // Do nothing, if the service is already running.  
  260.         if (mStarted == true) {  
  261.             Log.e(TAG, "Attempt to connect MQTT that is already active");  
  262.             return;  
  263.         }  
  264.   
  265.         // Establish an MQTT connection  
  266.         connect();  
  267.   
  268.         // Register a connectivity listener  
  269.         // registerReceiver(mConnectivityChanged, new  
  270.         // IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));  
  271.         IntentFilter filter = new IntentFilter("MESSAGE_ARRIVE_ACTION");  
  272.         filter.addAction("DELETE_MESSAGE_ACTION");  
  273.         registerReceiver(mMessageArrive, filter);  
  274.     }  
  275.   
  276.     private synchronized void stop() {  
  277.         // Do nothing, if the service is not running.  
  278.         if (mStarted == false) {  
  279.             Log.e(TAG, "Attempt to stop connection that not active.");  
  280.             return;  
  281.         }  
  282.   
  283.         // Save stopped state in the preferences  
  284.         setStarted(false);  
  285.   
  286.         // Remove the connectivity receiver  
  287.         // unregisterReceiver(mConnectivityChanged);  
  288.         unregisterReceiver(mMessageArrive);  
  289.         // Any existing reconnect timers should be removed, since we explicitly  
  290.         // stopping the service.  
  291.         cancelReconnect();  
  292.   
  293.         // Destroy the MQTT connection if there is one  
  294.         if (mConnection != null) {  
  295.             mConnection.disconnect();  
  296.             mConnection = null;  
  297.         }  
  298.     }  
  299.   
  300.     int index = 1000;  
  301.   
  302.     private synchronized void connect() {  
  303.         Log.i(TAG, "connect");  
  304.         // fetch the device ID from the preferences.  
  305.         // Create a new connection only if the device id is not NULL  
  306.         // TODO Auto-generated method stub  
  307.         String deviceID = mPrefs.getString(PREF_DEVICE_ID, null);  
  308.         index++;  
  309.         try {  
  310.             Log.i(TAG, "brokerHostName: " + MQTT_HOST + ", initTopic: "  
  311.                     + deviceID);  
  312.             mConnection = new MQTTConnection(MQTT_HOST, deviceID);  
  313.         } catch (MqttException e) {  
  314.             // Schedule a reconnect, if we failed to connect  
  315.             Log.e(TAG, "MQTTConnection MqttException "  
  316.                     + (e.getMessage() != null ? e.getMessage() : "NULL"));  
  317.             while (!isNetworkAvailable()) {  
  318.                 try {  
  319.                     Thread.sleep(1000);  
  320.                 } catch (InterruptedException e1) {  
  321.                     // TODO Auto-generated catch block  
  322.                     e1.printStackTrace();  
  323.                 }  
  324.             }  
  325.             if (isNetworkAvailable()) {  
  326.                 Log.e(TAG, "Network Available, scheduleReconnect");  
  327.                 scheduleReconnect(mStartTime);  
  328.             } else {  
  329.                 Log.e(TAG, "MqttException Network not Available");  
  330.             }  
  331.         }  
  332.         setStarted(true);  
  333.     }  
  334.   
  335.     private synchronized void keepAlive() {  
  336.         Log.i(TAG, "keepAlive");  
  337.         try {  
  338.             Log.i(TAG, "sendKeepAlive, mStarted: " + mStarted  
  339.                     + ", mConnection: " + mConnection);  
  340.             // Send a keep alive, if there is a connection.  
  341.             if (mStarted == true && mConnection != null) {  
  342.                 mConnection.sendKeepAlive();  
  343.             }  
  344.         } catch (MqttException e) {  
  345.             Log.e(TAG, "sendKeepAlive MqttException: "  
  346.                     + (e.getMessage() != null ? e.getMessage() : "NULL"));  
  347.             mConnection.disconnect();  
  348.             mConnection = null;  
  349.             cancelReconnect();  
  350.         }  
  351.     }  
  352.   
  353.     // Schedule application level keep-alives using the AlarmManager  
  354.   
  355.     /** 
  356.      * 启动心跳包闹钟 
  357.      */  
  358.     private void startKeepAlives() {  
  359.         Log.i(TAG, "startKeepAlives");  
  360.         Intent i = new Intent();  
  361.         i.setClass(this, PushService.class);  
  362.         i.setAction(ACTION_KEEPALIVE);  
  363.         PendingIntent pi = PendingIntent.getService(this0, i, 0);  
  364.         AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);  
  365.         alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,  
  366.                 System.currentTimeMillis() + KEEP_ALIVE_INTERVAL,  
  367.                 KEEP_ALIVE_INTERVAL, pi);  
  368.     }  
  369.   
  370.     // Remove all scheduled keep alives  
  371.     /** 
  372.      * 取消已经存在的闹钟 
  373.      */  
  374.     private void stopKeepAlives() {  
  375.         Log.i(TAG, "stopKeepAlives");  
  376.         Intent i = new Intent();  
  377.         i.setClass(this, PushService.class);  
  378.         i.setAction(ACTION_KEEPALIVE);  
  379.         PendingIntent pi = PendingIntent.getService(this0, i, 0);  
  380.         AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);  
  381.         alarmMgr.cancel(pi);  
  382.     }  
  383.   
  384.     // We schedule a reconnect based on the starttime of the service  
  385.     public void scheduleReconnect(long startTime) {  
  386.         // the last keep-alive interval  
  387.         Log.i(TAG, "scheduleReconnect");  
  388.         long interval = mPrefs.getLong(PREF_RETRY, INITIAL_RETRY_INTERVAL);  
  389.   
  390.         // Calculate the elapsed time since the start  
  391.         long now = System.currentTimeMillis();  
  392.         long elapsed = now - startTime;  
  393.   
  394.         // Set an appropriate interval based on the elapsed time since start  
  395.         if (elapsed < interval) {  
  396.             interval = Math.min(interval * 4, MAXIMUM_RETRY_INTERVAL);  
  397.         } else {  
  398.             interval = INITIAL_RETRY_INTERVAL;  
  399.         }  
  400.   
  401.         // Save the new internval  
  402.         Log.i(TAG, "Rescheduling connection interval:  " + interval + "(ms).");  
  403.         mPrefs.edit().putLong(PREF_RETRY, interval).commit();  
  404.   
  405.         // Schedule a reconnect using the alarm manager.  
  406.         Intent i = new Intent();  
  407.         i.setClass(this, PushService.class);  
  408.         i.setAction(ACTION_RECONNECT);  
  409.         PendingIntent pi = PendingIntent.getService(this0, i, 0);  
  410.         AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);  
  411.         alarmMgr.set(AlarmManager.RTC_WAKEUP, now + interval, pi);  
  412.     }  
  413.   
  414.     // Remove the scheduled reconnect  
  415.     public void cancelReconnect() {  
  416.         Log.i(TAG, "cancelReconnect");  
  417.         Intent i = new Intent();  
  418.         i.setClass(this, PushService.class);  
  419.         i.setAction(ACTION_RECONNECT);  
  420.         PendingIntent pi = PendingIntent.getService(this0, i, 0);  
  421.         AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);  
  422.         alarmMgr.cancel(pi);  
  423.     }  
  424.   
  425.     private synchronized void reconnectIfNecessary() {  
  426.         Log.i(TAG, "reconnectIfNecessary mStarted: " + mStarted  
  427.                 + ", mConnection: " + mConnection);  
  428.         if (mStarted == true && mConnection == null) {  
  429.             new Thread() {  
  430.                 public void run() {  
  431.                     connect();  
  432.                 }  
  433.             }.start();  
  434.         }  
  435.     }  
  436.   
  437.     // This receiver listeners for network changes and updates the MQTT  
  438.     // connection accordingly  
  439.     private BroadcastReceiver mConnectivityChanged = new BroadcastReceiver() {  
  440.         @Override  
  441.         public void onReceive(Context context, Intent intent) {  
  442.             Log.i(TAG, "mConnectivityChanged onReceive");  
  443.             // Get network info  
  444.             NetworkInfo info = (NetworkInfo) intent  
  445.                     .getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);  
  446.   
  447.             boolean isConnected = false;  
  448.             if (null != info) {  
  449.                 isConnected = info.isConnected();  
  450.             }  
  451.             Log.i(TAG, "Connectivity changed, isConnected: " + isConnected);  
  452.   
  453.             if (isConnected) {  
  454.                 reconnectIfNecessary();  
  455.                 Log.i(TAG, "reconnectIfNecessary");  
  456.             } else if (mConnection != null) {  
  457.                 // if there no connectivity, make sure MQTT connection is  
  458.                 // destroyed  
  459.                 mConnection.disconnect();  
  460.                 mConnection = null;  
  461.                 cancelReconnect();  
  462.                 Log.i(TAG, "make MQTT connection destroyed");  
  463.             }  
  464.         }  
  465.     };  
  466.   
  467.     public BroadcastReceiver mMessageArrive = new BroadcastReceiver() {  
  468.         @Override  
  469.         public void onReceive(Context arg0, Intent arg1) {  
  470.             Log.i(TAG, "mMessageArrive onReceive");  
  471.             // TODO Auto-generated method stub  
  472.             // Toast.makeText(mContext, "1", Toast.LENGTH_SHORT).show();  
  473.             if (arg1.getAction().equals("MESSAGE_ARRIVE_ACTION")) {  
  474.                 Bundle bundle = arg1.getExtras();  
  475.                 String account = bundle.getString("account");  
  476.                 String time = bundle.getString("time");  
  477.                 String type = bundle.getString("type");  
  478.                 String content = bundle.getString("content");  
  479.                 // Log.i(TAG, "111 account: " + account + ", time: " + time +  
  480.                 // ", type: " + type);  
  481.                 // Log.i(TAG, "222 content: " + content);  
  482.                 if (type.equals("5")) {// 视频  
  483.                     String[] mp4 = content.split(";"); // 多个视频用;隔开(文件名1;文件1url;文件名2;文件2url)  
  484.                     // Log.i(TAG, " 333 lenght: " + mp4.length + ", fileNum: " +  
  485.                     // mp4.length / 2);  
  486.                     for (int i = 0; i < mp4.length; i += 2) {  
  487.                         String mp4Content = mp4[i] + ";" + mp4[i + 1];  
  488.                         // Log.i(TAG, "444 mp4[" + i + "]: " + mp4[i] + "mp4[" +  
  489.                         // (i+1) + "]: " + mp4[i+1]);  
  490.                         // Log.i(TAG, "555 mp4Content: " + mp4Content);  
  491.                         dbManager.addMsg(new MessageItem(time, 1, Integer  
  492.                                 .parseInt(type), mp4Content, account));  
  493.                     }  
  494.   
  495.                     /* 
  496.                      * String[] mp4 = content.split("&&"); // 多个视频用&&隔开 for (int 
  497.                      * i = 0; i < mp4.length; i++) { Log.i("TAG", 
  498.                      * "333  mp4["+i+"]-->"+mp4[i]); dbManager.addMsg(new 
  499.                      * MessageItem(time, 1, Integer.parseInt(type), mp4[i], 
  500.                      * account)); } 
  501.                      */  
  502.                 } else if (type.equals("1")) {// 图片  
  503.                     String[] jpg = content.split(";");  
  504.                     // Log.i(TAG, "type jpg.length: " + jpg.length);  
  505.                     for (int i = 0; i < jpg.length; i++) {  
  506.                         dbManager.addMsg(new MessageItem(time, 1, Integer  
  507.                                 .parseInt(type), jpg[i], account));  
  508.                     }  
  509.                 } else {  
  510.                     dbManager.addMsg(new MessageItem(time, 1, Integer  
  511.                             .parseInt(type), content, account));  
  512.   
  513.                 }  
  514.                 MainActivity.mMsgHandler.sendEmptyMessage(0);  
  515.   
  516.                 MyNotification.getInstance(mContext).custom(  
  517.                         dbManager.getMsgNumber(), content);  
  518.                 MediaPlayer mMediaPlayer;  
  519.                 mMediaPlayer = MediaPlayer.create(mContext, R.raw.videorecord);  
  520.                 mMediaPlayer.setLooping(false);  
  521.                 try {  
  522.                     mMediaPlayer.prepare();  
  523.                 } catch (Exception e) {  
  524.                     e.printStackTrace();  
  525.                 }  
  526.                 mMediaPlayer.start();  
  527.   
  528.             } else if (arg1.getAction().equals("DELETE_MESSAGE_ACTION")) {  
  529.                 // Toast.makeText(mContext, "2", Toast.LENGTH_SHORT).show();  
  530.                 List<MessageItem> itemList = dbManager.getMsgItem();  
  531.                 for (MessageItem item : itemList) {  
  532.                     try {  
  533.                         // Toast.makeText(mContext, "3",  
  534.                         // Toast.LENGTH_SHORT).show();  
  535.                         if (mConnection != null) {  
  536.                             // Toast.makeText(mContext,  
  537.                             // "发送 time="+item.getmsgTime()+" size="+item.getmsgTime().length(),  
  538.                             // Toast.LENGTH_LONG).show();  
  539.                             mConnection.publishToTopic(  
  540.                                     MyState.getInstance().ucmUser + "_cb",  
  541.                                     item.getmsgTime() + "");  
  542.                             // Toast.makeText(mContext,  
  543.                             // "发过去了 "+MyState.getInstance().ucmUser+"_cb"+item.getmsgTime(),  
  544.                             // Toast.LENGTH_SHORT).show();  
  545.                         } else {  
  546.                             Toast.makeText(mContext, "连接断开了",  
  547.                                     Toast.LENGTH_SHORT).show();  
  548.                         }  
  549.                     } catch (MqttException e) {  
  550.                         // TODO Auto-generated catch block  
  551.                         e.printStackTrace();  
  552.                         Log.e("ttt""kkkkkk bad");  
  553.                     }  
  554.                 }  
  555.                 dbManager.deleteMsg();  
  556.             }  
  557.         }  
  558.     };  
  559.   
  560.     // Display the topbar notification  
  561.     private void showNotification(String text) {  
  562.         Log.i(TAG, "showNotification");  
  563.         Notification n = new Notification();  
  564.   
  565.         n.flags |= Notification.FLAG_SHOW_LIGHTS;  
  566.         n.flags |= Notification.FLAG_AUTO_CANCEL;  
  567.   
  568.         n.defaults = Notification.DEFAULT_ALL;  
  569.   
  570.         n.icon = R.drawable.logo;  
  571.         n.when = System.currentTimeMillis();  
  572.   
  573.         // Simply open the parent activity  
  574.         PendingIntent pi = PendingIntent.getActivity(this0new Intent(this,  
  575.                 MainActivity.class), 0);  
  576.   
  577.         // Change the name of the notification here  
  578.         n.setLatestEventInfo(this, NOTIF_TITLE, text, pi);  
  579.   
  580.         mNotifMan.notify(NOTIF_CONNECTED, n);  
  581.     }  
  582.   
  583.     // Check if we are online  
  584.     private boolean isNetworkAvailable() {  
  585.         NetworkInfo info = mConnMan.getActiveNetworkInfo();  
  586.         if (info != null) {  
  587.             return info.isConnected();  
  588.         }  
  589.         return false;  
  590.     }  
  591.   
  592.     // This inner class is a wrapper on top of MQTT client.  
  593.     private class MQTTConnection implements MqttSimpleCallback {  
  594.         IMqttClient mqttClient = null;  
  595.   
  596.         // Creates a new connection given the broker address and initial topic  
  597.         public MQTTConnection(String brokerHostName, String initTopic)  
  598.                 throws MqttException {  
  599.             // Create connection spec  
  600.             Log.i(TAG, "brokerHostName: " + brokerHostName + "initTopic: "  
  601.                     + initTopic);  
  602.             String mqttConnSpec = "tcp://" + brokerHostName + "@"  
  603.                     + MQTT_BROKER_PORT_NUM;  
  604.             // Create the client and connect  
  605.             mqttClient = new MqttClient(BROKER_URL,MQTT_PERSISTENCE);  
  606. //          mqttClient = MqttClient.createMqttClient(mqttConnSpec,  
  607. //                  MQTT_PERSISTENCE);  
  608.             String deviceId = mPrefs.getString(PREF_DEVICE_ID, "");  
  609.             String clientID = MQTT_CLIENT_ID + "/" + deviceId;  
  610.             Log.i(TAG, "clientID: " + clientID);  
  611.             String account = MyState.getInstance().ucmUser;  
  612.             clientID = "MT/" + account + "_" + Integer.toString(index);  
  613.             Log.i(TAG, "connect, clientID: " + clientID + ", cleanstart: "  
  614.                     + MQTT_CLEAN_START + ", keepalive: " + MQTT_KEEP_ALIVE);  
  615.             mqttClient.connect(clientID, MQTT_CLEAN_START, MQTT_KEEP_ALIVE);  
  616.   
  617.             // register this client app has being able to receive messages  
  618.             mqttClient.registerSimpleHandler(this);  
  619.   
  620.             // Subscribe to an initial topic, which is combination of client ID  
  621.             // and device ID.  
  622.             initTopic = MyState.getInstance().ucmUser;// + "/+";  
  623.             //initTopic = clientID + "@" + initTopic;  
  624.             Log.i(TAG, "subscribeToTopic initTopic: " + initTopic);  
  625.   
  626.             /* 
  627.              * Message msg = new Message(); msg.what = 4; msg.obj = initTopic; 
  628.              * hander.sendMessage(msg); 
  629.              */  
  630.             subscribeToTopic(initTopic);  
  631.   
  632.             // cancelReconnect();  
  633.             // Save start time  
  634.             mStartTime = System.currentTimeMillis();  
  635.             // Star the keep-alives  
  636.             startKeepAlives();  
  637.             // sendKeepAlive();  
  638.         }  
  639.   
  640.         // Disconnect  
  641.         public void disconnect() {  
  642.             Log.i(TAG, "disconnect");  
  643.             try {  
  644.                 stopKeepAlives();  
  645.                 mqttClient.disconnect();  
  646.                 mqttClient = null;  
  647.             } catch (MqttPersistenceException e) {  
  648.                 Log.e(TAG, "disconnect MqttException: "  
  649.                         + (e.getMessage() != null ? e.getMessage() : " NULL"));  
  650.             }  
  651.         }  
  652.   
  653.         /* 
  654.          * Send a request to the message broker to be sent messages published 
  655.          * with the specified topic name. Wildcards are allowed. 
  656.          */  
  657.         private void subscribeToTopic(String topicName) throws MqttException {  
  658.             Log.i(TAG, "subscribeToTopic, topicName:" + topicName);  
  659.             if ((mqttClient == null) || (mqttClient.isConnected() == false)) {  
  660.                 // quick sanity check - don't try and subscribe if we don't have  
  661.                 // a connection  
  662.                 Log.e(TAG, "subscribeToTopic :Connection error"  
  663.                         + "No connection");  
  664.             } else {  
  665.                 String[] topics = { topicName };  
  666.                 int subscribe = mqttClient.subscribe(topics,MQTT_QUALITIES_OF_SERVICE);  
  667.   
  668.                 Message msg = StatusBarManager.getInstance(mContext).mHandler  
  669.                         .obtainMessage();  
  670.                 msg.what = StatusBarManager.MSG_STATUS_IMAGE_MSG;  
  671.                 msg.arg1 = subscribe;  
  672.                 StatusBarManager.getInstance(mContext).onStatusChange(msg);  
  673.                 Log.e(TAG, "subscribe: " + subscribe + "  topicName:"  
  674.                         + topicName);  
  675.                 Log.e(TAG, "subscribeToTopic :topic=" + topicName);  
  676.             }  
  677.         }  
  678.   
  679.         /* 
  680.          * Sends a message to the message broker, requesting that it be 
  681.          * published to the specified topic. 
  682.          */  
  683.         public void publishToTopic(String topicName, String message)  
  684.                 throws MqttException {  
  685.             if ((mqttClient == null/* || (mqttClient.isConnected() == false) */) {  
  686.                 // quick sanity check - don't try and publish if we don't have  
  687.                 // a connection  
  688.                 Log.e(TAG, "publishToTopic, mqttClient is null");  
  689.                 // connect();  
  690.             } else {  
  691.                 mqttClient.publish(topicName, message.getBytes(),  
  692.                         MQTT_QUALITY_OF_SERVICE, MQTT_RETAINED_PUBLISH);  
  693.                 Log.i(TAG, "publishToTopic, topicName: " + topicName  
  694.                         + ", message: " + message);  
  695.             }  
  696.         }  
  697.   
  698.         /* 
  699.          * Called if the application loses it's connection to the message 
  700.          * broker. 
  701.          */  
  702.         public void connectionLost() throws Exception {  
  703.             Log.e(TAG, "connectionLost" + " connection downed");  
  704.             stopKeepAlives();  
  705.             mConnection = null;  
  706.             new Thread() {  
  707.                 public void run() {  
  708.                     int i = 0;  
  709.                     while (i < 10) {  
  710.                         if (isNetworkAvailable() == true) {  
  711.                             Log.e(TAG,  
  712.                                     "network available, reconnectIfNecessary");  
  713.                             reconnectIfNecessary();  
  714.                             break;  
  715.                         } else {  
  716.                             Log.e(TAG, "network not available, sleep");  
  717.                             i++;  
  718.                             try {  
  719.                                 Thread.sleep(1000);  
  720.                             } catch (InterruptedException e) {  
  721.                                 // TODO Auto-generated catch block  
  722.                                 e.printStackTrace();  
  723.                             }  
  724.                         }  
  725.                     }  
  726.                 }  
  727.             }.start();  
  728.         }  
  729.   
  730.         /* 
  731.          * Called when we receive a message from the message broker. 
  732.          */  
  733.         public void publishArrived(String topicName, byte[] payload, int qos,  
  734.                 boolean retained) {  
  735.             // 如果没在群组内,直接return,只有在群组中才能接收消息  
  736.             if (!sta.isgrp) {  
  737.                 return;  
  738.             }  
  739.             // Show a notification  
  740.             String msg = new String(payload);  
  741.             // Toast.makeText(mContext, s, Toast.LENGTH_LONG).show();  
  742.             // showNotification(s);  
  743.             int msgNumber = mContext.getSharedPreferences("msg"0).getInt(  
  744.                     "msgNumber"0);  
  745.             msgNumber++;// 每来一次消息推送,消息数量加1  
  746.             // Log.i(TAG, "msgNumber: " + msgNumber);  
  747.             SharedPreferences sp = getSharedPreferences("msg"0);  
  748.             sp.edit().putInt("msgNumber", msgNumber).commit();  
  749.   
  750.             int badgeCount = msgNumber;  
  751.             ShortcutBadger.applyCount(mContext, badgeCount);  
  752.             Log.e(TAG, "cpublishArrived topic: " + topicName + ", msg: " + msg);  
  753.             if (msg.length() > 17) {  
  754.                 String time = msg.substring(016);  
  755.                 // Toast.makeText(mContext,  
  756.                 // "接收 time="+time+" size="+time.length(),  
  757.                 // Toast.LENGTH_LONG).show();  
  758.                 String type = msg.substring(1617);  
  759.                 String content = msg.substring(17);  
  760.                 Intent i = new Intent("MESSAGE_ARRIVE_ACTION");  
  761.                 i.putExtra("account", topicName);  
  762.                 i.putExtra("time", time);  
  763.                 i.putExtra("type", type);  
  764.                 i.putExtra("content", content);  
  765.                 mContext.sendBroadcast(i);  
  766.                 // Log.i(TAG, "sendBroadcast over");  
  767.             }  
  768.         }  
  769.   
  770.         public void sendKeepAlive() throws MqttException {  
  771.             Log.i(TAG, "Sending keepalive");  
  772.             // publish to a keep-alive topic  
  773.             publishToTopic(MQTT_CLIENT_ID + "/keepalive",  
  774.                     mPrefs.getString(PREF_DEVICE_ID, "123"));  
  775.         }  
  776.     }  
  777. }  
 需要请自行下载 .jar都在 demo 里面,包括java服务端和Android 客户端

转载地址:https://blog.csdn.net/cai784921129/article/details/53437299

猜你喜欢

转载自blog.csdn.net/qq1620851849/article/details/80003890