package com.lotaai.canguiayw.mqtt;
|
|
import android.app.Service;
|
import android.content.Context;
|
import android.content.Intent;
|
import android.net.ConnectivityManager;
|
import android.net.NetworkInfo;
|
import android.os.Handler;
|
import android.os.IBinder;
|
import android.os.Message;
|
import android.telecom.Call;
|
import android.util.Log;
|
|
import androidx.annotation.Nullable;
|
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.blankj.utilcode.util.CacheDiskUtils;
|
import com.blankj.utilcode.util.GsonUtils;
|
import com.blankj.utilcode.util.JsonUtils;
|
import com.blankj.utilcode.util.LogUtils;
|
import com.blankj.utilcode.util.StringUtils;
|
import com.lotaai.canguiayw.common.SettingConfig;
|
import com.lotaai.canguiayw.device.CanGuiCommand;
|
import com.lotaai.canguiayw.device.DeviceMessage;
|
import com.lotaai.canguiayw.device.DeviceType;
|
import com.lotaai.canguiayw.device.MessageType;
|
import com.lotaai.canguiayw.device.service.CrontrolGridModel;
|
import com.lotaai.canguiayw.smiledialog.TimeRunTextView;
|
import com.lotaai.canguiayw.sqllitedb.Order;
|
import com.lotaai.canguiayw.sqllitedb.OrderDetail;
|
import com.lotaai.canguiayw.sqllitedb.SqlliteDbManage;
|
|
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.MqttCallback;
|
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 org.greenrobot.eventbus.Subscribe;
|
import org.greenrobot.eventbus.ThreadMode;
|
|
public class MyMQTTService extends Service {
|
|
public static final String TAG = MyMQTTService.class.getSimpleName();
|
private static MqttAndroidClient client;
|
private MqttConnectOptions conOpt;
|
private static String pubTopic="cangui/device/send/";
|
private static String subTopic_Order="cangui/device/recvorder/";
|
private static String subTopic_Control="cangui/device/recvcontrol/";
|
|
@Override
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
init();
|
EventBus.getDefault().register(MyMQTTService.this);
|
return super.onStartCommand(intent, flags, startId);
|
}
|
|
@Subscribe(threadMode = ThreadMode.ASYNC)
|
public void publish(DeviceMessage message) {
|
//需要在这个地方区分是哪种指令
|
//才能确定发送到哪个topic
|
LogUtils.i("接收到通知",message.getMsgString());
|
if (message.getMessageType() == MessageType.MQTT.ordinal()){
|
String topic = subTopic_Control + CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Code);
|
Integer qos = 2;
|
Boolean retained = false;
|
String msg = message.getMsgString();
|
try {
|
client.publish(topic, msg.getBytes(), qos.intValue(), retained.booleanValue());
|
} catch (MqttException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
private void init() {
|
// 服务器地址(协议+地址+端口号)
|
String uri = "tcp://" + SettingConfig.getInstance().MQTT_IP+":"+SettingConfig.getInstance().MQTT_PORT;;
|
LogUtils.i(uri);
|
client = new MqttAndroidClient(this, uri, CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Code));
|
// 设置MQTT监听并且接受消息
|
client.setCallback(mqttCallback);
|
conOpt = new MqttConnectOptions();
|
// 清除缓存 客户端掉线后 服务器端不会清除session,当重连后可以接收之前订阅主题的消息
|
conOpt.setCleanSession(false);
|
// 设置超时时间,单位:秒
|
conOpt.setConnectionTimeout(10);
|
// 心跳包发送间隔,单位:秒
|
conOpt.setKeepAliveInterval(20);
|
// 用户名
|
conOpt.setUserName(SettingConfig.getInstance().MQTT_USER);
|
// 密码
|
conOpt.setPassword(SettingConfig.getInstance().MQTT_PASSWORD.toCharArray());
|
//设置自动重连
|
conOpt.setAutomaticReconnect(true);
|
|
// last will message
|
boolean doConnect = true;
|
String message ="";
|
Integer qos = 2;
|
Boolean retained = false;
|
if ((!message.equals("")) || (!pubTopic.equals(""))) {
|
// 最后
|
try {
|
conOpt.setWill(pubTopic, message.getBytes(), qos.intValue(), retained.booleanValue());
|
} catch (Exception e) {
|
Log.i(TAG, "Exception Occured", e);
|
doConnect = false;
|
iMqttActionListener.onFailure(null, e);
|
}
|
}
|
if (doConnect) {
|
doClientConnection();
|
}
|
}
|
|
@Override
|
public void onDestroy() {
|
try {
|
client.disconnect(); //服务销毁,断开连接
|
} catch (MqttException e) {
|
e.printStackTrace();
|
}
|
super.onDestroy();
|
}
|
|
/**
|
* 连接MQTT服务器
|
*/
|
private void doClientConnection() {
|
Thread sysc = new Thread() {
|
@Override
|
public void run() {
|
while (!client.isConnected()) {
|
try {
|
Thread.sleep(5*1000);
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
}
|
if (isConnectIsNomarl()) {
|
try {
|
LogUtils.i("doClientConnection start");
|
client.connect(conOpt, null, iMqttActionListener);
|
} catch (MqttException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}
|
};
|
SettingConfig.getInstance().getExecutor().execute(sysc);
|
}
|
|
// MQTT是否连接成功
|
private IMqttActionListener iMqttActionListener = new IMqttActionListener() {
|
|
@Override
|
public void onSuccess(IMqttToken arg0) {
|
LogUtils.i(TAG, "连接成功 ");
|
try {
|
// 订阅myTopic话题,当订阅多条频道,需要遍历逐条订阅,否则有可能订阅失败
|
String gui = CacheDiskUtils.getInstance().getString(SettingConfig.getInstance().Cache_Device_Code);
|
client.subscribe(subTopic_Order+gui, 2);
|
client.subscribe(subTopic_Control+gui, 2);
|
} catch (MqttException e) {
|
e.printStackTrace();
|
}
|
}
|
|
@Override
|
public void onFailure(IMqttToken arg0, Throwable arg1) {
|
arg1.printStackTrace();
|
LogUtils.i(TAG, "连接失败:" + arg1);
|
}
|
};
|
|
// MQTT监听并且接受消息
|
private MqttCallback mqttCallback = new MqttCallback() {
|
|
@Override
|
public void messageArrived(String topic, MqttMessage message) throws Exception {
|
String messageStr = new String(message.getPayload());
|
String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
|
LogUtils.i(TAG, "messageArrived:" + messageStr);
|
LogUtils.i(TAG, str2);
|
//对接收到的数据做分析
|
//1、订单数据
|
if (topic.startsWith(subTopic_Order)){
|
Order order = new Order();
|
JSONObject json = JSONObject.parseObject(messageStr);
|
String orderno = json.getString("orderno");
|
//判断这个订单是否已经存在
|
Order checkOrder = SqlliteDbManage.getInstance().selectOrtder(orderno);
|
if (checkOrder == null){
|
String seqnum = json.getString("seqnum");
|
String orderType = json.getString("orderType");
|
String bookingType = json.getString("bookingType");
|
String orderId = json.getString("orderId");
|
if (json.getString("startTime")!=null) {
|
String startTime = JsonUtils.getString(messageStr, "startTime", "");
|
}
|
String createdTime = json.getString("createdTime");
|
String tableNum = JsonUtils.getString(messageStr,"tableNum","");
|
order.setOrderNo(orderno);
|
order.setOrderId(orderId);
|
order.setState(0);
|
order.setXuHao(seqnum);
|
order.setTakeCode("");
|
order.setGridNo("");
|
order.setPutInDate("");
|
order.setCreateTime(createdTime);
|
JSONArray detailArry = json.getJSONArray("orderItems");
|
if (detailArry!=null && detailArry.size()>0){
|
for (int i = 0; i < detailArry.size(); i++) {
|
JSONObject orderGoodsDTO = detailArry.getJSONObject(i).getJSONObject("orderGoods");
|
if (orderGoodsDTO!=null){
|
OrderDetail detail = new OrderDetail();
|
String name = orderGoodsDTO.getString("name");
|
String numString = orderGoodsDTO.getString("num");
|
int num =1;
|
if (!numString.isEmpty()){
|
num = Integer.parseInt(numString);
|
}
|
detail.setOrderNo(orderno);
|
detail.setNum(num);
|
detail.setItemName(name);
|
SqlliteDbManage.getInstance().insertOrUpdateOrderDetailInfo(detail);
|
}
|
}
|
}
|
SqlliteDbManage.getInstance().insertOrderInfo(order);
|
DeviceMessage sendMessage = new DeviceMessage();
|
sendMessage.setMessageType(MessageType.NEWORDER.ordinal());
|
sendMessage.setMsgString(orderno);
|
EventBus.getDefault().post(sendMessage);
|
}
|
}
|
//2、开门、开馆灯、开关消毒灯、开关加热
|
if (topic.startsWith(subTopic_Control)){
|
JSONObject json = JSONObject.parseObject(messageStr);
|
if (json.getString("action") !=null && json.getString("action").equals(DeviceAction.CONTROLDEVICE.name())){
|
String doorIsOpen = json.getString(DeviceAction.doorIsOpen.name());
|
String xiaoDuIsOpen = json.getString(DeviceAction.xiaoDuIsOpen.name());
|
String jiareIsOpen = json.getString(DeviceAction.jiareIsOpen.name());
|
String dengGuangIsOpen = json.getString(DeviceAction.dengGuangIsOpen.name());
|
String grid = json.getString("gridNo");
|
//将格子号转换成柜号和格子
|
CrontrolGridModel crontrolGridModel = new CrontrolGridModel();
|
crontrolGridModel.ChangeGrid(grid);
|
if (doorIsOpen!=null && doorIsOpen.equals("1")){
|
crontrolGridModel.setOpenOrNoActon(1);
|
}
|
if (xiaoDuIsOpen!=null) {
|
crontrolGridModel.setXiaodu(Integer.parseInt(xiaoDuIsOpen));
|
}
|
if (jiareIsOpen!=null) {
|
crontrolGridModel.setXiaodu(Integer.parseInt(jiareIsOpen));
|
}
|
if (dengGuangIsOpen!=null) {
|
crontrolGridModel.setXiaodu(Integer.parseInt(dengGuangIsOpen));
|
}
|
LogUtils.i("控制",crontrolGridModel.getGuiNo(),crontrolGridModel.getGridNo(),crontrolGridModel.getOpenOrNoActon());
|
byte[] command = CanGuiCommand.getInstance().controlGridCommand(crontrolGridModel.getGuiNo() ,
|
crontrolGridModel.getGridNo() , crontrolGridModel.getOpenOrNoActon(),
|
crontrolGridModel.getWendu(), crontrolGridModel.getXiaodu(), crontrolGridModel.getDengGuang(),
|
crontrolGridModel.getJiaRe(), crontrolGridModel.getGuangDengji());
|
DeviceMessage dvmessage = new DeviceMessage();
|
dvmessage.setMessageType(MessageType.SENDMESSAGE.ordinal());
|
dvmessage.setDeviceType(DeviceType.CANGUI.ordinal());
|
dvmessage.setMessageByte(command);
|
EventBus.getDefault().post(dvmessage);
|
//判断是否是取餐的,如果是取餐的,需要将这个订单从本地删除掉
|
String qucan = json.getString("qucan");
|
if (qucan!=null && "1".equals(qucan)){
|
SqlliteDbManage.getInstance().deleteFromOrderByGridNo(grid);
|
SqlliteDbManage.getInstance().updateGridByStr(grid,0);
|
}
|
}
|
}
|
}
|
|
@Override
|
public void deliveryComplete(IMqttDeliveryToken arg0) {
|
|
}
|
|
@Override
|
public void connectionLost(Throwable arg0) {
|
|
}
|
};
|
|
/**
|
* 判断网络是否连接
|
*/
|
private boolean isConnectIsNomarl() {
|
ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
|
if (info != null && info.isAvailable()) {
|
String name = info.getTypeName();
|
Log.i(TAG, "MQTT当前网络名称:" + name);
|
return true;
|
} else {
|
Log.i(TAG, "MQTT 没有可用网络");
|
return false;
|
}
|
}
|
|
@Nullable
|
@Override
|
public IBinder onBind(Intent intent) {
|
return null;
|
}
|
}
|