package com.jd.aiadAndroid.commonlib.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.google.gson.JsonObject;
import com.jd.aiadAndroid.commonlib.bean.Audio;
import com.jd.aiadAndroid.commonlib.bean.Reboot;
import com.jd.aiadAndroid.commonlib.bean.ScreenShot;
import com.jd.aiadAndroid.commonlib.bean.SoftDeviceOff;
import com.jd.aiadAndroid.commonlib.bean.Topics;
import com.jd.aiadAndroid.commonlib.interfaces.IOnPlayStrategyArrivedCallback;
import com.jd.aiadAndroid.commonlib.utils.BaseUtil;
import com.jd.aiadAndroid.commonlib.utils.Constants;
import com.jd.aiadAndroid.commonlib.utils.GsonUtil;
import com.jd.aiadAndroid.commonlib.utils.JsonObjectBuilder;
import com.jd.aiadAndroid.commonlib.utils.SPUtils;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;
import java.util.HashMap;
import static org.eclipse.paho.client.mqttv3.MqttConnectOptions.MQTT_VERSION_3_1_1;
/**
* MQTT长连接服务
*
* @author cjq
* @version 创建时间:2019/01/19 16:06
*/
public class MqttService extends Service {
public static final String TAG = MqttService.class.getSimpleName();
private static MqttAndroidClient client;
private MqttConnectOptions conOpt;
private static IOnPlayStrategyArrivedCallback mOnPlayStrategyArrived;
private static Integer requestId = 0;
private boolean isFirst = true;
public static HashMap requestCallBackListeners = new
HashMap<>();
public static void setOnPlayStrategyArrivedCallback(IOnPlayStrategyArrivedCallback onPlayStrategyArrivedCallback) {
mOnPlayStrategyArrived = onPlayStrategyArrivedCallback;
}
public interface OnRequestCallBackListener {
void onRequestCallBack(String response);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand: startId = " + startId);
init();
return START_STICKY;
}
public class MyBinder extends Binder {
public MqttService getService() {
return MqttService.this;
}
}
private MyBinder myBinder = new MyBinder();
@Override
public IBinder onBind(Intent intent) {
init();
return myBinder;
}
public static void request(String topic, String msg, OnRequestCallBackListener
requestCallBackListener) {
try {
Integer qos = 1;
Boolean retained = false;
int reqid = requestId++;
JsonObjectBuilder build = new JsonObjectBuilder();
build.append("reqId", reqid);
JsonObject body = new JsonObject();
body.addProperty("msg", msg);
body.addProperty("route", "/aaaa");
build.append("body", body);
requestCallBackListeners.put(reqid, requestCallBackListener);
if (client.isConnected()) {
IMqttDeliveryToken token = client.publish(topic, build.toString().getBytes(), qos
.intValue(), retained.booleanValue());
Log.i(TAG, "AiAD.LOG Mqtt request: token = " + token.getMessage().toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void init() {
// 服务器地址(协议+地址+端口号)
client = new MqttAndroidClient(this, Topics.TCP_URL, Topics.PREFIX + Topics.CLIENT_ID);
// 设置MQTT监听并且接受消息
client.setCallback(mqttCallback);
conOpt = new MqttConnectOptions();
// 设置超时时间,单位:秒
conOpt.setConnectionTimeout(1);
// 心跳包发送间隔,单位:秒
conOpt.setKeepAliveInterval(20);
//自动重连
conOpt.setAutomaticReconnect(true);
conOpt.setMqttVersion(MQTT_VERSION_3_1_1);
conOpt.setCleanSession(false);//默认为true,为实现离线推送给,将其保留
// 用户名
conOpt.setUserName(Topics.USERNAME);
// 密码
conOpt.setPassword(Topics.PASSWORD.toCharArray());
Integer qos = 1;
Boolean retained = false;
Boolean doConnect = true;
// 最后的遗嘱
try {
conOpt.setWill(Topics.GLOBAL_REQ + "disconnect", "Connection Closed".getBytes(), qos
.intValue(), retained.booleanValue());
} catch (Exception e) {
Log.i(TAG, "Mqtt Connection Exception Occured", e);
doConnect = false;
iMqttActionListener.onFailure(null, e);
}
//开始连接
if (doConnect) doClientConnection();
}
@Override
public void onDestroy() {
try {
Log.i(TAG, "AiAD.LOG Mqtt onDestroy");
if (client != null) {
client.unregisterResources();
client.close();
client = null;
}
} catch (Exception e) {
e.printStackTrace();
}
super.onDestroy();
}
/**
* 连接MQTT服务器
*/
private void doClientConnection() {
while (true) {
try {
if (client != null && !client.isConnected()) {
client.connect(conOpt, this, iMqttActionListener);
break;
} else {
break;
}
} catch (Exception e) {
e.printStackTrace();
continue;
}
}
}
// MQTT是否连接成功
private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken arg0) {
Log.i(TAG, "AiAD.LOG Mqtt Connection 连接成功 ");
//订阅subscribeTopic话题
Log.i(TAG, "AiAD.LOG Mqtt onSuccess: SUBSCRIBE_TOPIC_MAC = " + Topics.SUBSCRIBE_TOPIC_MAC);
subscribeTopics();
}
@Override
public void onFailure(IMqttToken arg0, Throwable arg1) {
arg1.printStackTrace();
// 连接失败,重连
Log.i(TAG, "AiAD.LOG Mqtt Connection onFailure--->第一次连接失败");
doClientConnection();
}
};
private void subscribeTopics() {
try {
if (!isFirst) return;
if (client == null) return;
client.subscribe(Topics.SUBSCRIBE_TOPIC, 1);
client.subscribe(Topics.SUBSCRIBE_TOPIC_MAC, 1);
client.subscribe(Topics.GLOBAL_PUSH, 1);
Log.i(TAG, "AiAD.LOG Mqtt subscribeTopics 订阅成功");
//客户端发送defaultTopic请求
// request(Topics.DEFAULT_TOPIC, "bababaab", new OnRequestCallBackListener() {
// @Override
// public void onRequestCallBack(String response) {
//
// }
// });
isFirst = false;
} catch (MqttException e) {
e.printStackTrace();
}
}
// MQTT监听并且接受消息
private MqttCallbackExtended mqttCallback = new MqttCallbackExtended() {
@Override
public void connectComplete(boolean reconnect, String serverURI) {
Log.i(TAG, "AiAD.LOG Mqtt connectComplete: reconnect = " + reconnect);
}
/**
* 连接服务器成功后,服务器应答信息格式:
*
* @param topic 话题
* @param message 下发的消息
*/
@Override
public void messageArrived(String topic, MqttMessage message) {
try {
String str1 = new String(message.getPayload());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
}
@Override
public void connectionLost(Throwable arg0) {
if (!BaseUtil.isNetworkAvailable(MqttService.this)) {
Log.i("connectionLost", "AiAD.LOG Mqtt Connection connectionLost--->网络不可用");
}
// 失去连接,重连
if (arg0 != null)
Log.i("connectionLost", "AiAD.LOG Mqtt Connection connectionLost--->失去连接,重连" + arg0.getMessage());
doClientConnection();
}
};
}
注意事项:
1.bindservice()
2.结束程序时候,必须先unbinddervice(),关闭mqtt client,否则client非正常关闭,下次重启会有 重复消息推送,应该是本地缓存的,不是service的
3.setCleanSession(false);//默认为true,为实现离线推送设置为false