How to publish only one message using a Java MQTT client using Eclipse Paho
我正在为我的大学期末作业做一个项目。
我想做一个使用 MQTT 协议与我的树莓派通信的 android 应用程序。
为此,我使用了蚊子代理,但是当我使用 Eclipse Paho 使用 Java MQTT 客户端在代理中发布消息时,我的应用程序发布了 5 次相同的消息,我不知道问题是否出在我的班级发布消息,或者我的类 on_create() of android.
我的代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | public class MainActivity extends AppCompatActivity implements View.OnClickListener { EditText distanceCondition; EditText timeCondition; EditText countCondition; String distance; String time; String count; String topic; int notificationID = 1; int functionality; int ok = 1; public void mqttconnect(final String topic, final String message){ final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(),"tcp://192.168.1.36","androidSampleClient"); mqttAndroidClient.setCallback(new MqttCallback() { //iot.eclipse.org:1883 @Override public void connectionLost(Throwable cause) { System.out.println("Connection was lost!"); } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { System.out.println("Message Arrived!:" + topic +":" + new String(message.getPayload())); //displayNotification("DETECT MOVEMENT! visit LCESS app now."); JSONObject inf = new JSONObject(Arrays.toString(message.getPayload())); try { if (inf.optString("Functionality").equals(6)) { if (inf.optString("ok").equals(1)) { displayNotification("DETECT MOVEMENT! visit LCESS app now."); } } if (inf.optString("Functionality").equals(7)) { if (inf.optString("ok").equals(1)) { displayNotification("DETECT MOVEMENT IN" + inf.optString("Distance") +" CM! visit LCESS app now."); } } if (inf.optString("Functionality").equals(8)) { if (inf.optString("ok").equals(1)) { displayNotification("DETECT MOVEMENT IN" + inf.optString("Time") +" HOURS! visit LCESS app now."); } } if (inf.optString("Functionality").equals(9)) { if (inf.optString("ok").equals(1)) { displayNotification("DETECT MOVEMENT IN" + inf.optString("Distance") +" CM and in" + inf.optString("Time") +" HOURS! visit LCESS app now."); } } if (inf.optString("Functionality").equals(10)) { if (inf.optString("ok").equals(1)) { displayNotification("DETECT" + inf.optString("Count") +" OBJECTS/PERSONS! visit LCESS app now."); } } } catch (Exception functionality){ } } @Override public void deliveryComplete(IMqttDeliveryToken token) { System.out.println("Delivery Complete!"); } }); try { mqttAndroidClient.connect(null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { System.out.println("Connection Success!"); try { System.out.println("Subscribing to:"+ topic); mqttAndroidClient.subscribe(topic, 0); System.out.println("Subscribed to:"+ topic); System.out.println("Publishing message.."); mqttAndroidClient.publish(topic, new MqttMessage(message.getBytes())); } catch (MqttException ex) { } } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { System.out.println("Connection Failure!"); } }); } catch (MqttException ex) { } } public JSONObject sendJSONmessage() { topic ="Mesurement"; distance = distanceCondition.getText().toString(); time = timeCondition.getText().toString(); count = countCondition.getText().toString(); JSONObject post_dict = new JSONObject(); try { post_dict.put("Topic", topic); post_dict.put("ok" ,ok); post_dict.put("Functionality", functionality); post_dict.put("Distance", distance); post_dict.put("Time", time); post_dict.put("Count", count); } catch (JSONException e) { e.printStackTrace(); } if (post_dict.length() > 0) { System.out.println(post_dict); } return post_dict; } protected void displayNotification(CharSequence contentText){ Intent i = new Intent(this, NotificationActivity.class); i.putExtra("notificationID", notificationID); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i, 0); NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); CharSequence ticker ="Notification in LCESS"; CharSequence contentTitle ="LCESS"; Notification noti = new NotificationCompat.Builder(this) .setContentIntent(pendingIntent) .setTicker(ticker) .setContentTitle(contentTitle) .setContentText(contentText) .setSmallIcon(R.drawable.lcess) .addAction(R.drawable.lcess, ticker, pendingIntent) .setVibrate(new long[] {100, 250, 100, 500}) .build(); nm.notify(notificationID, noti); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); distanceCondition = (EditText) findViewById(R.id.edit_detectDistanceCondition); timeCondition = (EditText) findViewById(R.id.edit_detectTimeCondition); countCondition = (EditText) findViewById(R.id.edit_countDetects); Button button_detectDistance = (Button) findViewById(R.id.button_detectDistance); Button button_detectDistanceCondition = (Button) findViewById(R.id.button_detectDistanceCondition); Button button_detectTimeCondition = (Button) findViewById(R.id.button_detectTimeCondition); Button button_detectIfAllCondition = (Button) findViewById(R.id.button_detectIfAllCondition); Button button_count = (Button) findViewById(R.id.button_count); assert button_detectDistance != null; /*button_detectDistance.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { functionality = 1; mqttconnect("Device1/Detect", sendJSONmessage().toString()); } });*/ button_detectDistance.setOnClickListener(this); assert button_detectDistanceCondition != null; button_detectDistanceCondition.setOnClickListener(this); assert button_detectTimeCondition != null; button_detectTimeCondition.setOnClickListener(this); assert button_detectIfAllCondition != null; button_detectIfAllCondition.setOnClickListener(this); assert button_count != null; button_count.setOnClickListener(this); } public void onClick(View v){ if (R.id.button_detectDistance==v.getId()){ functionality = 1; mqttconnect("Mesurement", sendJSONmessage().toString()); } else if (R.id.button_detectDistanceCondition==v.getId()){ functionality = 2; mqttconnect(sendJSONmessage().optString(topic), sendJSONmessage().toString()); } else if (R.id.button_detectTimeCondition==v.getId()){ functionality = 3; mqttconnect(sendJSONmessage().optString(topic), sendJSONmessage().toString()); } else if (R.id.button_detectIfAllCondition==v.getId()){ functionality = 4; mqttconnect("Device1/Detect1", sendJSONmessage().toString()); } else if (R.id.button_count==v.getId()){ functionality = 5; mqttconnect("Device1/Detect1", sendJSONmessage().toString()); } } |
}
首先,我创建了 Mqtt 类来发布和订阅主题,之后,该类以 JSON 格式发布我需要的消息。
下一个类我用它来显示一个通知。
最后是 onCreate() 和 onClick 类,我在其中声明了我的按钮、edittext...以及我放置发布消息的条件的地方。
更具体地说,当按下按钮时,我会在 JSON 格式的主题中发布消息。
应用程序运行良好。但问题是:
如何在代理中只发布一条消息?
在下图中,您可以看到当我按下按钮时如何发布 5 条消息。
红色的你可以看到消息发布了 5 或 6 次
1 2 3 4 5 6 | String msg ="{"uuid":"12345678"}"; MqttMessage m = new MqttMessage(); m.setPayload(msg.getBytes()); m.setQos(2); m.setRetained(false); mqttAndroidClient.publish(topic, m); |
我解决了这个问题。
在这种情况下,我如何构建一个与代理连接的函数,每次单击某个按钮时,我都会再次发布并订阅该主题。只有我必须订阅一次。
解决方案是连接中断并订阅主题,仅一次,因此我们实现相同的代码但在 onCreate() 方法中。