如何使用 Eclipse Paho 使用 Java MQTT 客户端仅发布一条消息
How to publish only one message using a Java MQTT client using Eclipse Paho
我正在为大学期末作业做一个项目。
我想做一个 android 应用程序,它使用 MQTT 协议与我的 raspberry pi 通信。
为此,我使用了一个 mosquitto 代理,但是当我使用 Java MQTT 客户端使用 Eclipse Paho 在代理中发布消息时,我的应用程序发布了相同的消息 5 次,我不知道是不是错误是我的class发布消息,还是我的classon_create()android.
我的代码如下:
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 class 来发布和订阅主题,之后,class 以 JSON 格式发布我需要的消息。
下一个class我用它来显示通知。
最后,我在 onCreate() 和 onClick class 中声明了我的按钮、编辑文本……以及我放置条件以发布消息的地方。
更具体地说,当按下一个按钮时,我以 JSON 格式在主题中发布一条消息。
App 运行 很好。但问题是:
我如何才能在代理中只发布一条消息?
在下图中,您可以看到当我按下按钮时如何发布 5 条消息。
In red you can see the message published 5 or 6 times
我解决了这个问题。
在这种情况下,我如何构建一个函数来连接代理,每次我单击某个按钮时,我都会再次发布和订阅该主题。而且只有我必须订阅一次。
解决方案是连接到坏掉的主题并订阅主题,只有一次,因此我们实现了相同的代码,但在 onCreate() 方法中。
String msg = "{\"uuid\":\"12345678\"}";
MqttMessage m = new MqttMessage();
m.setPayload(msg.getBytes());
m.setQos(2);
m.setRetained(false);
mqttAndroidClient.publish(topic, m);
我正在为大学期末作业做一个项目。 我想做一个 android 应用程序,它使用 MQTT 协议与我的 raspberry pi 通信。 为此,我使用了一个 mosquitto 代理,但是当我使用 Java MQTT 客户端使用 Eclipse Paho 在代理中发布消息时,我的应用程序发布了相同的消息 5 次,我不知道是不是错误是我的class发布消息,还是我的classon_create()android.
我的代码如下:
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 class 来发布和订阅主题,之后,class 以 JSON 格式发布我需要的消息。
下一个class我用它来显示通知。 最后,我在 onCreate() 和 onClick class 中声明了我的按钮、编辑文本……以及我放置条件以发布消息的地方。 更具体地说,当按下一个按钮时,我以 JSON 格式在主题中发布一条消息。
App 运行 很好。但问题是: 我如何才能在代理中只发布一条消息?
在下图中,您可以看到当我按下按钮时如何发布 5 条消息。 In red you can see the message published 5 or 6 times
我解决了这个问题。 在这种情况下,我如何构建一个函数来连接代理,每次我单击某个按钮时,我都会再次发布和订阅该主题。而且只有我必须订阅一次。 解决方案是连接到坏掉的主题并订阅主题,只有一次,因此我们实现了相同的代码,但在 onCreate() 方法中。
String msg = "{\"uuid\":\"12345678\"}";
MqttMessage m = new MqttMessage();
m.setPayload(msg.getBytes());
m.setQos(2);
m.setRetained(false);
mqttAndroidClient.publish(topic, m);