2017-02-12 2 views
1

앱을 처음 열면 브로커 정보를 입력하고 시도해보고 저장할 수있는 화면이 필요합니다.Paho MqttClient를 사용하여 안드로이드에서 Mqtt 연결 시도하기

시도를 클릭하면 정보가 성공적인 연결을 위해 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 MQTT를위한'onSuccess' 콜백이 있습니다. 브로커에 대한 연결이 성공하면 해당 메소드가 호출됩니다. 그래서 당신이해야 할 일은'subscribe' 메소드를 호출하고 여러분이 구독하는'topic'을 매개 변수로 전달하는 것입니다. 어떤 오류 또는 특정 문제가 있습니까? –

+0

사실 나는 어디에서 시작 해야할지 모르겠다는 많은 것들을 시도했다. 나는 "ServiceConnection"을 사용하고 서비스를 바인딩하면서 유튜브에서 비디오를 보았지만 아무 것도 할 수 없었다. 구독하려고하면 null 객체 참조에서> org.eclipse.paho.android.service.MqttAndroidClient.subscribe (java.lang.String, int) '를 얻습니다. 또한 구독하려면 IMqttToken이 필요합니까? 그래서 잃어버린, 미안 해요 ... 나는 서비스 내부에서 메서드를 호출하는 적절한 방법을 이해하지 못합니다. –

관련 문제