title: Trying to keep MQTT client connection even when app is closed
body: <p>I am currently using MQTT protocol in my android app and I am able to receive messages when my app is open or when it is running in the background however when i close my app completely the connection is lost and I am not longer able to receive messages. I need to be able to still recieve messages as I want the message to trigger an activity in my app to launch. Here are the files that I am using to implement MQTT. MQTTHelper class: EDIT. Ive have tried to implement a service but it still doesnt seem to be working.Does Anyone know what I am doing wrong?</p>
  
  <pre><code>package com.example.carcrashdetection.helpers;
  
  import android.app.Service;
  import android.content.BroadcastReceiver;
  import android.content.Context;
  import android.content.Intent;
  import android.content.IntentFilter;
  import android.net.wifi.WifiInfo;
  import android.net.wifi.WifiManager;
  import android.os.Handler;
  import android.os.IBinder;
  import android.util.Log;
  import android.widget.Toast;
  
  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.MqttCallback;
  import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
  import org.eclipse.paho.client.mqttv3.MqttException;
  import org.eclipse.paho.client.mqttv3.MqttMessage;
  
  public class MqttHelper extends Service {
          public MqttAndroidClient mqttAndroidClient;
           BroadcastReceiver m_ScreenOffReceiver;
          final String serverUri = "tcp://hairdresser.cloudmqtt.com:15767";
  
          final String clientId = "CarCrashDetection";
          final String subscriptionTopic = "Topic/+";
  
          final String username = "username";
          final String password = "password";
  
      @Override
      public void onCreate() {
          super.onCreate();
          registerReceiver();
          new Thread(new Runnable() {
              @Override
              public void run() {
                  MqttHelper.this.connect();
              }
          }).start();
      }
          public MqttHelper(Context context){
              mqttAndroidClient = new MqttAndroidClient(context, serverUri, clientId);
              mqttAndroidClient.setCallback(new MqttCallback() {
  
  
                  public void connectComplete(boolean b, String 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(MqttCallback callback) {
              mqttAndroidClient.setCallback(callback);
          }
  
          private void connect(){
              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) {
  
                          DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions();
                          disconnectedBufferOptions.setBufferEnabled(true);
                          disconnectedBufferOptions.setBufferSize(100);
                          disconnectedBufferOptions.setPersistBuffer(false);
                          disconnectedBufferOptions.setDeleteOldestMessages(false);
                          mqttAndroidClient.setBufferOpts(disconnectedBufferOptions);
                          subscribeToTopic();
                      }
  
                      @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();
              }
          }
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          //do something
          return START_STICKY;
      }
  
      @Override
      public IBinder onBind(Intent intent) {
          return null;
      }
  
      private void registerReceiver(){
          m_ScreenOffReceiver = new BroadcastReceiver(){
              @Override
              public void onReceive(final Context context, Intent intent){
                  //Log.d(TAG,"onReceive of Wifi_State_Change called");
                  if(intent.getAction().equals(WifiManager.WIFI_STATE_CHANGED_ACTION))
                  {
                      int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
                      if(wifiState != WifiManager.WIFI_STATE_ENABLED)
                          return;
  
                      final WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
                      new Handler().postDelayed(new Runnable() {
                          @Override
                          public void run() {
                              WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                              String ssid = wifiInfo.getSSID();
  
                              Toast.makeText(context, "active wifi:" + ssid, Toast.LENGTH_SHORT).show();
  
                              //You can connect to the your mqtt broker again:
                              connect();
                          }
                      }, 10000);
                  }
              }
          };
  
          IntentFilter intentFilter = new IntentFilter();
          intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
          registerReceiver(m_ScreenOffReceiver, intentFilter);
      }
      @Override
      public void onDestroy() {
          if(mqttAndroidClient!=null) {
          /*unregisterResources is needed,otherwise receive this error:
            has leaked ServiceConnection org.eclipse.paho.android.service.MqttAndroidClient*/
              try {
                  mqttAndroidClient.unregisterResources();
                  mqttAndroidClient.close();
                  mqttAndroidClient.disconnect();
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
          unregisterReceiver(m_ScreenOffReceiver);
          m_ScreenOffReceiver = null;
  
          super.onDestroy();
      }
      }
  
  
  </code></pre>
  
  <p>MainActivity </p>
  
  <pre><code>private void startMqtt(){
          mqttHelper = new MqttHelper(getApplicationContext());
          mqttHelper.setCallback(new MqttCallbackExtended(){
              @Override
              public void connectComplete(boolean b, String s) {
                  Toast.makeText(MainActivity.this, "connected ", Toast.LENGTH_SHORT).show();
  
              }
              public void connectionLost(Throwable throwable){
                  Toast.makeText(MainActivity.this,"Disconnected", Toast.LENGTH_SHORT).show();
  
              }
              public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception{
                  Log.e("message ", String.valueOf(mqttMessage));
                  Toast.makeText(MainActivity.this, "Crash Occurred", Toast.LENGTH_SHORT).show();
                  Intent intent = new Intent(MainActivity.this, alert.class);
                  startActivity(intent);
  
              }
              public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken){
  
              }
          });
      }
  </code></pre>
  
  <p>I've been searching for a while now but cant seem to find anything that works. I thought it would be an easy fix but its hasn't been for me. Any help would be much appreciated. </p>