2017-02-12 15 views
1

Когда вы впервые открываете приложение, я хочу, чтобы на экране вы могли ввести информацию о брокере и нажать кнопку «Попробовать и сохранить».Пытаясь подключиться к Mqtt на Android с помощью Paho MqttClient

При нажатии кнопки «Попробовать» следует просто показать Snackbar, если информация делает успешное соединение.

Это код, который я называю, когда кнопка попытки нажата:

private void tryConnection(View v){ 
    if(verifyInputs()){ 
     Snackbar.make(v, getString(R.string.trying_connection), Snackbar.LENGTH_LONG).show(); 

     String clientId = MqttClient.generateClientId(); 
     MqttAndroidClient client = 
       new MqttAndroidClient(this.getApplicationContext(), getServerAddress(), 
         clientId); 

     try { 
      IMqttToken token = client.connect(); 
      final View vinner = v; 
      token.setActionCallback(new IMqttActionListener() { 
       @Override 
       public void onSuccess(IMqttToken asyncActionToken) { 
        // We are connected 
        Snackbar.make(vinner, "Success", Snackbar.LENGTH_LONG).show(); 

       } 

       @Override 
       public void onFailure(IMqttToken asyncActionToken, Throwable exception) { 
        // Something went wrong e.g. connection timeout or firewall problems 
        Snackbar.make(vinner, "Fail", Snackbar.LENGTH_LONG).show(); 
       } 
      }); 
     } catch (MqttException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Проблема заключается в том, onFailure, кажется, не будет вызван, когда он не может подключиться к серверу, но когда соединение к сервер потерян.

Как просто проверить соединение, чтобы сохранить его и вернуться к основному виду деятельности?

ответ

1

Хорошо, поэтому я не могу видеть ваш полный сервис, любую другую реализацию или как/где вы используете это, поэтому я предоставляю образец моей службы MQTT.

Возможно, вы сможете сравнить его, найти проблему и исправить ее.

Или вы можете просто использовать мою реализацию. Вам решать. Надеюсь, поможет.

import android.app.Service; 
import android.content.Intent; 
import android.os.Binder; 
import android.os.Handler; 
import android.os.IBinder; 
import android.support.annotation.Nullable; 
import android.util.Log; 

import org.eclipse.paho.android.service.MqttAndroidClient; 
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; 
import org.eclipse.paho.client.mqttv3.MqttSecurityException; 
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; 

import java.util.ArrayList; 

public class MyMqttService extends Service implements MqttCallback, IMqttActionListener { 

    private final IBinder binder = new MyBinder(); 

    private MqttAndroidClient mqttClient; 
    private MqttConnectOptions mqttConnectOptions; 
    private static final MemoryPersistence persistence = new MemoryPersistence(); 
    private ArrayList<MqttAndroidClient> lostConnectionClients; 

    private String clientId = ""; 
    private boolean isReady = false; 
    private boolean doConnectTask = true; 
    private boolean isConnectInvoked = false; 

    private Handler handler = new Handler(); 
    private final int RECONNECT_INTERVAL = 10000; // 10 seconds 
    private final int DISCONNECT_INTERVAL = 20000; // 20 seconds 
    private final int CONNECTION_TIMEOUT = 60; 
    private final int KEEP_ALIVE_INTERVAL = 200; 

    private String broker_url = "my_broker"; 

    public MyMqttService() {} 

    public class MyBinder extends Binder { 
     public MyMqttService getService() { 
      return MyMqttService.this; 
     } 
    } 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return binder; 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     initMqttClient(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 

     disconnectClients(); 
     if (isConnectInvoked && mqttClient != null && mqttClient.isConnected()) { 
      try { 
       // unsubscribe here 
       unsubscribe("¯\\_(ツ)_/¯"); 
       mqttClient.disconnect(); 
      } catch (MqttException e) { 
       Log.e("TAG", e.toString()); 
      } 
     } 

     handler.removeCallbacks(connect); 
     handler.removeCallbacks(disconnect); 
    } 

    private void initMqttClient() { 
     if(mqttClient != null) { 
      mqttClient = null; 
     } 

     lostConnectionClients = new ArrayList<>(); 

     mqttConnectOptions = new MqttConnectOptions(); 
     mqttConnectOptions.setCleanSession(true); 
     mqttConnectOptions.setConnectionTimeout(CONNECTION_TIMEOUT); 
     mqttConnectOptions.setKeepAliveInterval(KEEP_ALIVE_INTERVAL); 

     setNewMqttClient(); 

     handler.post(connect); 
     handler.postDelayed(disconnect, DISCONNECT_INTERVAL); 
    } 

    private void setNewMqttClient() { 
     mqttClient = new MqttAndroidClient(MyMqttService.this, broker_url, clientId, persistence); 
     mqttClient.setCallback(this); 
    } 

    public Runnable connect = new Runnable() { 
     public void run() { 
      connectClient(); 
      handler.postDelayed(connect, RECONNECT_INTERVAL); 
     } 
    }; 

    public Runnable disconnect = new Runnable() { 
     public void run() { 
      disconnectClients(); 
      handler.postDelayed(disconnect, DISCONNECT_INTERVAL); 
     } 
    }; 

    private void connectClient() { 
     if(doConnectTask) { 
      doConnectTask = false; 

      try { 
       isConnectInvoked = true; 
       mqttClient.connect(mqttConnectOptions, null, this); 
      } catch (MqttException ex) { 
       doConnectTask = true; 
       Log.e("TAG", ex.toString()); 
      } 
     } 
    } 

    private void disconnectClients() { 
     if (lostConnectionClients.size() > 0) { 
      // Disconnect lost connection clients 
      for (MqttAndroidClient client : lostConnectionClients) { 
       if (client.isConnected()) { 
        try { 
         client.disconnect(); 
        } catch (MqttException e) { 
         Log.e("TAG", e.toString()); 
        } 
       } 
      } 

      // Close already disconnected clients 
      for (int i = lostConnectionClients.size() - 1; i >= 0; i--) { 
       try { 
        if (!lostConnectionClients.get(i).isConnected()) { 
         MqttAndroidClient client = lostConnectionClients.get(i); 
         client.close(); 
         lostConnectionClients.remove(i); 
        } 
       } catch (IndexOutOfBoundsException e) { 
        Log.e("TAG", e.toString()); 
       } 
      } 
     } 
    } 

    @Override 
    public void deliveryComplete(IMqttDeliveryToken token) { 
     Log.e("TAG", "deliveryComplete()"); 
    } 

    @Override 
    public void messageArrived(String topic, MqttMessage message) throws Exception { 
     String payload = new String(message.getPayload()); 
     // do something 
    } 

    @Override 
    public void connectionLost(Throwable cause) { 
     Log.e("TAG", cause.getMessage()); 
    } 

    @Override 
    public void onSuccess(IMqttToken iMqttToken) { 
     isReady = true; 

     // subscribe here 
     subscribe("¯\\_(ツ)_/¯"); 
    } 

    @Override 
    public void onFailure(IMqttToken iMqttToken, Throwable throwable) { 
     setNewMqttClient(); 
     isReady = false; 
     doConnectTask = true; 
     isConnectInvoked = false; 
    } 

    private void subscribe(String topic) { 
     try { 
      mqttClient.subscribe(topic, 0); 
      isReady = true; 
     } catch (MqttSecurityException mqttSexEx) { 
      isReady = false; 
     } catch (MqttException mqttEx) { 
      isReady = false; 
     } 
    } 

    private void unsubscribe(String topic) { 
     try { 
      mqttClient.unsubscribe(topic); 
     } catch (MqttSecurityException mqttSecEx) { 
      Log.e("TAG", mqttSecEx.getMessage()); 
     } catch (MqttException mqttEx) { 
      Log.e("TAG", mqttEx.getMessage()); 
     } 
    } 

    private void publish(String topic, String jsonPayload) { 
     if(!isReady) { 
      return; 
     } 

     try { 
      MqttMessage msg = new MqttMessage(); 
      msg.setQos(0); 
      msg.setPayload(jsonPayload.getBytes("UTF-8")); 
      mqttClient.publish(topic, msg); 
     } catch (Exception ex) { 
      Log.e("TAG", ex.toString()); 
     } 
    } 
} 

Мое другое предложение было бы просто настроить локальную трансляцию, когда ваши нагрузки активности и запуска службы, если служба MQTT может подключиться, вы отправляете широковещательные изречение подключен и вы показываете Snackbar. Если соединение не выполнено, вы отправляете другую трансляцию и показываете другое сообщение.

+0

привет! Я использую ваш сервис или, по крайней мере, пытаюсь. Не могли бы вы объяснить мне, как я могу подписаться? Я полностью потерял, был на это в течение часа –

+0

@NelsonSilva существует обратный вызов 'onSuccess' для MQTT. Как только соединение с брокером будет успешным, этот метод будет вызван. Итак, все, что вам нужно сделать, это вызвать метод 'subscribe' и перейти в« тему », на которую вы подписались как параметр. Вы получаете какие-либо ошибки или какие-либо конкретные проблемы? –

+0

На самом деле я пробовал так много вещей, что я не знаю, с чего начать. Я смотрю видео на YouTube, используя «ServiceConnection» и привязывая службу, но я не могу никуда не попасть. когда я пытаюсь подписаться, я получаю a> org.eclipse.paho.android.service.MqttAndroidClient.subscribe (java.lang.String, int) 'на ссылке нулевого объекта. Кроме того, чтобы подписаться, мне нужен IMqttToken? Я так потерял, извините ... Я не понимаю, как правильно вызвать метод изнутри службы. –