关于 android:如何使用 Eclipse Paho 使用 Java MQTT 客户端仅发布一条消息

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() 方法中。