2017-09-15 145 views
0

我有一個廣播接收器,它檢查WIFI_STATE_CHANGE以查看我是否已連接到某個WiFi網絡。例如,如果我回家,我想要發送某個MQTT消息。我遇到的問題是,它僅在第一次運行應用程序時連接併發送MQTT消息。嘗試使用廣播接收器在連接WiFi時連接到MQTT服務器(Paho)

過程:

  1. 如果我構建應用程序和設備上運行它,它認識我的家庭Wi-Fi發送消息。
  2. 我關閉設備上的Wifi,然後再次打開。
  3. 當MQTT連接到服務器無法建立時,我收到「Failure」消息。

我需要的是,我重新連接到網絡後,而不是「失敗」獲得「連接」,但不知何故它永遠不會發生......什麼可能是錯的?

PS。我認爲這與事實有關,當檢測到WiFi時,廣播接收器運行連接代碼,雖然互聯網在該時間點不可用(獲得IP等)。

這裏是廣播接收器:

package me.app.comehomedemo; 
 

 
import ... 
 
    
 

 
public class SynchronizeBroadcastReceiver extends BroadcastReceiver { 
 

 

 
    
 
    MqttAndroidClient client; 
 
    static String MQTTHOST = "myhost"; 
 
    static String USERNAME = "myusername"; 
 
    static String PASSWORD = "mypassword"; 
 
    static String topicStr = "/topic/mac/control"; 
 
    static String payload = "1"; 
 

 

 
    @Override 
 
    public void onReceive(final Context context, Intent intent) { 
 

 

 
     NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 
 

 

 
     if (info.isConnected()) { 
 

 

 
      WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 
 
      WifiInfo wifiInfo = wifiManager.getConnectionInfo(); 
 

 
      int ip = wifiInfo.getIpAddress(); 
 

 
      Toast.makeText(context, String.valueOf(ip), Toast.LENGTH_SHORT).show(); 
 

 

 
      String ssid = wifiInfo.getSSID(); 
 

 
      if (ssid.equals("\"mySSID\"")) { 
 

 

 
       String clientId = MqttClient.generateClientId(); 
 
      client = new MqttAndroidClient(context.getApplicationContext(), MQTTHOST, clientId); 
 
      MqttConnectOptions options = new MqttConnectOptions(); 
 
      options.setUserName(USERNAME); 
 
      options.setPassword(PASSWORD.toCharArray()); 
 
     // options.setAutomaticReconnect(true); 
 

 

 

 

 
        try { 
 
         IMqttToken token = client.connect(options); 
 
         token.setActionCallback(new IMqttActionListener() { 
 
          @Override 
 
          public void onSuccess(IMqttToken asyncActionToken) { 
 
           // We are connected 
 
           Toast.makeText(context, "Connected", Toast.LENGTH_SHORT).show(); 
 
           try { 
 

 
            client.publish(topicStr, payload.getBytes(), 0, false); 
 
           } catch (MqttException e) { 
 
            e.printStackTrace(); 
 
           } 
 
          } 
 

 
          @Override 
 
          public void onFailure(IMqttToken asyncActionToken, Throwable exception) { 
 
           // Something went wrong e.g. connection timeout or firewall problems 
 
           Toast.makeText(context, "Failure", Toast.LENGTH_SHORT).show(); 
 

 
          } 
 
         }); 
 
        } catch (MqttException e) { 
 
         e.printStackTrace(); 
 
        } 
 

 

 
       Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 
 
       MediaPlayer mp = MediaPlayer.create(context.getApplicationContext(), notification); 
 
       mp.start(); 
 

 

 
      } 
 

 
     } 
 
    } 
 

 
    }

回答

0

我設法通過等待2秒鐘,然後運行任務來解決它。使用this解決方案,它的工作。我不得不等待互聯網連接做好準備!

0

由於等待2秒鐘已經解決了您的問題,因此可能是因爲MQTT連接和發佈數據包之前建立了連接(如DHCP爲您的手機IP並建立路由)之前,Wifi廣播來得太早妥善交付。

但是,如果其他用戶需要等待10秒而不是2秒,會發生什麼?

我的建議是自動重新連接選項中MqttConnectOptions設置,然後使用該連接回調發布所需信息的經紀人,最後斷開在發佈的回調:

private IMqttActionListener mConnectCallback = new IMqttActionListener() { 
    @Override 
    public void onSuccess(IMqttToken token) { 
     try { 
      client.publish(topicStr, new MqttMessage(payload.getBytes()), null, mPublishCallback); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

    @Override 
    public void onFailure(IMqttToken token, Throwable ex) { 
    } 
}; 

private IMqttActionListener mPublishCallback = new IMqttActionListener() { 
    @Override 
    public void onSuccess(IMqttToken token) { 
     // TODO disconnect 
    } 

    @Override 
    public void onFailure(IMqttToken token, Throwable ex) { 
    } 
}; 

MqttAndroidClient client = new MqttAndroidClient(context, MQTTHOST, "my_id"); 
MqttConnectOptions options = new MqttConnectOptions(); 
options.setUserName(USERNAME); 
options.setPassword(PASSWORD.toCharArray()); 
options.setAutomaticReconnect(true); 
client.connect(options, null, mConnectCallback); 
+0

出於某種原因,我沒有管理,使用你的代碼工作。回調從未被調用。還有一個「mClient」包含可能成爲客戶端的代碼。 –