MQTT是一个轻量级的消息发布/订阅协议,它是实现基于手机客户端的消息推送服务器的理想解决方案。
首先是配置Android端的依赖
dependencies{
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
}
添加权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
注册Service:
<service android:name=".MqttMsgService"/>
Android 端代码MqttMsgService实现:
public class MqttMsgService extends Service {
@Override
public void onCreate() {
super.onCreate();
Log.e("MqttMsgService 创建了");
EventBus.getDefault().register(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("MqttMsgService 启动了");
//启动线程连接mqtt
new Thread(new Runnable() {
@Override
public void run() {
connectMqtt();
}
}).start();
return START_NOT_STICKY;
}
/**
* 订阅mqtt
*/
private void connectMqtt() {
//mqtt管理类用来管理mqtt连接
MqttManager.getInstance(this).createConnect(Network.BASE_MQTT_URL, Network.BASE_MQTT_USENAME, Network.BASE_MQTT_PASSWORD);
MqttUtils.online(getApplicationContext());
threadHeartbat = new MqttMsgService.HeartbeatThread();
Thread thread = new Thread(threadHeartbat);
thread.start();
}
}
//使用eventbus接收mqtt回传的消息(这个可以自行选择)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onInviteMsg(JSONObject jsonObject) {
Log.e("mq", "mq 收到消息" + jsonObject.toString());
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("MqttMsgService 退出了");
MqttManager.getInstance(this).close();
EventBus.getDefault().unregister(this);
}
Android 端代码MqttManager的实现:
public class MqttManager {
// 单例
private static MqttManager mInstance = null;
// 回调
private MqttCallback mCallback;
private MqttClient client;
private MqttConnectOptions conOpt;
private static String host = "http//:xxxxxxx.xxx.com";
private static String userName = null;
private static String password = null;
private static int qas[];
private Context context;
private MqttManager(Context context) {
mCallback = new MqttCallbackBus(context);
this.context = context;
}
public static MqttManager getInstance(Context context) {
if (null == mInstance) {
mInstance = new MqttManager(context);
}
return mInstance;
}
/**
* 释放单例, 及其所引用的资源
*/
public static void release() {
try {
if (mInstance != null) {
mInstance.disConnect();
mInstance = null;
}
} catch (Exception e) {
}
}
/**
* 创建Mqtt 连接
*
* @param brokerUrl Mqtt服务器地址(tcp://xxxx:1863)
* @param userName 用户名
* @param password 密码
* @return
*/
public boolean createConnect(String brokerUrl, String userName, String password) {
this.userName = userName;
this.password = password;
topics = new String[]{"xxx", "xxx2"}; //注册xxx,xxx2主题,邀请
qas = new int[]{1, 1};
//设备唯一识别号
String deviceId = AndroidUtil.getDeviceID(context);
if (client != null && client.isConnected()) {
return true;
}
boolean flag = false;
String tmpDir = System.getProperty("java.io.tmpdir");
MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(tmpDir);
try {
// Construct the connection options object that contains connection parameters
// such as cleanSession and LWT
conOpt = new MqttConnectOptions();
conOpt.setCleanSession(true);
conOpt.setKeepAliveInterval(20);
if (password != null) {
conOpt.setPassword(password.toCharArray());
}
if (userName != null) {
conOpt.setUserName(userName);
}
client = new MqttClient(brokerUrl, deviceId, dataStore);
// Set this wrapper as the callback handler
client.setCallback(mCallback);
flag = doConnect();
client.subscribe(topics, qas);
} catch (MqttException e) {
Log.e("mq : " + e.getMessage());
}
return flag;
}
/**
* 建立连接
*
* @return
*/
private boolean doConnect() {
boolean flag = false;
if (client != null) {
try {
client.connect(conOpt);
Log.e("mq to " + client.getServerURI() + " with client ID " + client.getClientId());
flag = true;
} catch (Exception e) {
Log.e("mq " + e.toString());
e.printStackTrace();
}
}
return flag;
}
/**
* Publish / send a message to an MQTT server
*
* @param topicName the name of the topic to publish to
* @param qos the quality of service to delivery the message at (0,1,2)
* @param payload the set of bytes to send to the MQTT server
* @return boolean
*/
public boolean publish(String topicName, int qos, byte[] payload) {
boolean flag = false;
try {
if (client == null) {
createConnect(host, userName, password);
}
if (!client.isConnected()) {
this.reconnect();
}
// Create and configure a message
MqttMessage message = new MqttMessage(payload);
message.setQos(qos);
client.publish(topicName, message);
flag = true;
} catch (MqttException e) {
Log.e("mq", e.toString());
}
return flag;
}
/**
* Subscribe to a topic on an MQTT server
* Once subscribed this method waits for the messages to arrive from the server
* that match the subscription. It continues listening for messages until the enter key is
* pressed.
*
* @param topicName to subscribe to (can be wild carded)
* @param qos the maximum quality of service to receive messages at for this subscription
* @return boolean
*/
private boolean subscribe(String topicName, int qos) {
boolean flag = false;
if (client != null && client.isConnected()) {
// Subscribe to the requested topic
// The QoS specified is the maximum level that messages will be sent to the client at.
// For instance if QoS 1 is specified, any messages originally published at QoS 2 will
// be downgraded to 1 when delivering to the client but messages published at 1 and 0
// will be received at the same level they were published at.
Log.d("Subscribing to topic \"" + topicName + "\" qas " + qos);
try {
client.subscribe(topicName, qos);
flag = true;
} catch (MqttException e) {
}
}
return flag;
}
private boolean subscribe(String[] topicName, int qos[]) {
boolean flag = false;
if (client != null && client.isConnected()) {
try {
client.subscribe(topicName, qos);
flag = true;
} catch (MqttException e) {
SaveLogUtils.saveInfo("mq subscribe error " + e.toString());
}
} else {
SaveLogUtils.saveInfo("mq subscribe error connect fail ");
}
return flag;
}
/**
* 取消连接
*
* @throws MqttException
*/
public void disConnect() throws MqttException {
if (client != null && client.isConnected()) {
client.disconnect();
}
}
public void close() {
if (client != null && client.isConnected()) {
try {
client.disconnect();
} catch (MqttException e) {
Log.e("mq " + e.toString());
e.printStackTrace();
}
}
}
public void reconnect() {
if (client != null && !client.isConnected()) {
SaveLogUtils.saveInfo("mq reconnect");
try {
client.setCallback(mCallback);
client.connect(conOpt);
client.subscribe(topics, qas);
// MqttUtils.online(this.context);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
}
Android 端代码MqttCallbackBus的实现:
public class MqttCallbackBus implements MqttCallback {
private Context mContext;
public MqttCallbackBus(Context mContext) {
this.mContext = mContext;
}
@Override
public void connectionLost(Throwable cause) {
Log.e(cause.getMessage());
EventBus.getDefault().post("连接中断");
}
@Override
public void messageArrived(String topic, MqttMessage message) {
Log.d(topic + "====" + message.toString());
if (!message.isRetained()) {
if (topic.equals("xxx")) {
Map msgMap = new HashMap<>();
msgMap.put("topic", MqttMsgService.OTHER_LOGIN);
msgMap.put("msg", message.toString());
EventBus.getDefault().post(msgMap);//收到xxx的消息
}
if (topic.equals("xxx2")) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(message.toString());
EventBus.getDefault().post(jsonObject);//收到xxx2的消息
} catch (JSONException e) {
e.printStackTrace();
}
}
} else {
Log.e("收到老消息", "。。。。。");
}
}
}
这样就简单的完成了MQTT了