2016-11-04 2 views
1

Je fais un projet pour mon travail universitaire final. Je veux faire une application Android qui communique avec mon pi de framboise en utilisant le protocole MQTT. Pour ce faire, j'utilise un courtier mosquitto, mais lorsque je publie un message dans un courtier utilisant le client Java MQTT en utilisant Eclipse Paho, mon application publie le même message 5 fois, et je ne sais pas si la faute est de mon classe qui publie un message, ou de ma classe on_create() d'android.Comment publier un seul message en utilisant un client Java MQTT en utilisant Eclipse Paho

Mon code est le suivant:

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()); 
    } 
} 

}

D'abord, j'ai créé la classe mqtt de publier et abonnez-vous au sujet, après, la classe de publier le message que j'ai besoin JSON format.

La classe suivante je l'utilise pour afficher une notification. Et enfin, les classes onCreate() et onClick où j'ai déclaré mes boutons, edittext ... Et où j'ai mis les conditions pour publier un message. Plus concrètement, lorsque j'appuie sur un bouton, je publie un message dans un sujet au format JSON.

L'application fonctionne bien. Mais la question est: Comment puis-je publier SEULEMENT un message dans un courtier?

Dans l'image suivante, vous pouvez voir comment publier un message lorsque j'appuie sur le bouton. In red you can see the message published 5 or 6 times

Répondre

0

J'ai résolu le problème. Dans ce cas, comment je construis une fonction pour se connecter avec le courtier, chaque fois que je clique sur certains boutons, je publie et souscrire à nouveau à la rubrique. et seulement je dois m'abonner une fois. La solution est de se connecter au cassé et de s'abonner au sujet, une seule fois, donc nous implémentons le même code mais dans la méthode onCreate().

0
String msg = "{\"uuid\":\"12345678\"}"; 
MqttMessage m = new MqttMessage(); 
m.setPayload(msg.getBytes()); 
m.setQos(2); 
m.setRetained(false); 
mqttAndroidClient.publish(topic, m);