title: MQTT send message from main thread
body: <p>I have simple MQTT subscriber implemented in <code>MqttHelper</code> class that works fine and receives subscriptions. But how I should deal when I need to send message to server from main program. I have method <code>publish</code> that works fine from <code>IMqttActionListener</code> but how to send text from main program on button pressed event?</p>
  
  <pre><code>package com.kkk.mqtt.helpers;
  
  import android.content.Context;
  import android.util.Log;
  
  import org.eclipse.paho.android.service.MqttAndroidClient;
  import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions;
  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.MqttCallbackExtended;
  import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
  import org.eclipse.paho.client.mqttv3.MqttException;
  import org.eclipse.paho.client.mqttv3.MqttMessage;
  
  import java.io.UnsupportedEncodingException;
  
  public class MqttHelper {
      public MqttAndroidClient mqttAndroidClient;
  
      final String serverUri = "tcp://tailor.cloudmqtt.com:16424";
  
      final String clientId = "ExampleAndroidClient";
      public final String subscriptionTopic = "sensor";
  
      final String username = "xxx";
      final String password = "yyy";
  
  
  
      public MqttHelper(Context context){
          mqttAndroidClient = new MqttAndroidClient(context, serverUri, clientId);
  
          mqttAndroidClient.setCallback(new MqttCallbackExtended() {
              @Override
              public void connectComplete(boolean b, String s) {
                  Log.w("mqtt", s);
              }
  
              @Override
              public void connectionLost(Throwable throwable) {
  
              }
  
              @Override
              public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
                  Log.w("Mqtt", mqttMessage.toString());
              }
  
              @Override
              public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
  
              }
          });
          connect();
      }
  
      public void setCallback(MqttCallbackExtended callback) {
          mqttAndroidClient.setCallback(callback);
      }
  
  
      public void publish(String topic, String info)
      {
  
  
          byte[] encodedInfo = new byte[0];
          try {
              encodedInfo = info.getBytes("UTF-8");
              MqttMessage message = new MqttMessage(encodedInfo);
              mqttAndroidClient.publish(topic, message);
              Log.e ("Mqtt", "publish done");
          } catch (UnsupportedEncodingException | MqttException e) {
              e.printStackTrace();
              Log.e ("Mqtt", e.getMessage());
          }catch (Exception e) {
              Log.e ("Mqtt", "general exception "+e.getMessage());
          }
  
      }
  
      private void connect(){
          Log.w("Mqtt", "connect start " );
          MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
          mqttConnectOptions.setAutomaticReconnect(true);
          mqttConnectOptions.setCleanSession(false);
          mqttConnectOptions.setUserName(username);
          mqttConnectOptions.setPassword(password.toCharArray());
  
          try {
  
              mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener()
              {
                  @Override
                  public void onSuccess(IMqttToken asyncActionToken) {
                      Log.w("Mqtt", "onSuccess " );
                      DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
                      disconnectedBufferOptions.setBufferEnabled(true);
                      disconnectedBufferOptions.setBufferSize(100);
                      disconnectedBufferOptions.setPersistBuffer(false);
                      disconnectedBufferOptions.setDeleteOldestMessages(false);
                      mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
                      subscribeToTopic();
                      publish(MqttHelper.this.subscriptionTopic,"information");
                  }
  
                  @Override
                  public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                      Log.w("Mqtt", "Failed to connect to: " + serverUri + exception.toString());
                  }
              });
  
  
          } catch (MqttException ex){
              ex.printStackTrace();
          }
      }
  
  
      private void subscribeToTopic() {
          try {
              mqttAndroidClient.subscribe(subscriptionTopic, 0, null, new IMqttActionListener() {
                  @Override
                  public void onSuccess(IMqttToken asyncActionToken) {
                      Log.w("Mqtt","Subscribed!");
                  }
  
                  @Override
                  public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                      Log.w("Mqtt", "Subscribed fail!");
                  }
              });
  
          } catch (MqttException ex) {
              System.err.println("Exception whilst subscribing");
              ex.printStackTrace();
          }
      }
  }
  </code></pre>
  
  <p>Code that starts MQTT subscriber:</p>
  
  <pre><code>private void startMqtt() {
      mqttHelper = new MqttHelper(getApplicationContext());
      mqttHelper.setCallback(new MqttCallbackExtended()
      {
          @Override
          public void connectComplete(boolean b, String s) {
              Log.w("Mqtt", "Connect complete"+ s );
          }
  
          @Override
          public void connectionLost(Throwable throwable) {
              Log.w("Mqtt", "Connection lost" );
          }
  
          @Override
          public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
              Log.w("Mqtt", mqttMessage.toString());
              dataReceived.setText(mqttMessage.toString());
          }
  
          @Override
          public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
              Log.w("Mqtt", "Delivery complete" );
  
          }
      });
      Log.w("Mqtt", "will publish");
  
  
  }
  </code></pre>