连接WiFi时尝试使用广播接收器连接到MQTT服务器(Paho)

时间:2017-09-15 21:06:21

标签: mqtt android-wifi paho

我有一个广播接收器,它检查WIFI_STATE_CHANGE以查看我是否已连接到某个WiFi网络。例如,如果我要回家,我想要发送某个MQTT消息。我遇到的问题是它只在第一次运行应用程序时连接并发送MQTT消息。

过程:

  1. 如果我构建应用程序并在设备上运行它并识别我的家庭WiFi它会发送消息。
  2. 我从设备关闭Wifi,然后重新打开。
  3. 我得到"失败"当无法建立与服务器的MQTT连接时,这是一条消息。
  4. 我需要的是在我重新连接到网络后,而不是"失败"得到"连接"但不知怎的,它永远不会发生......可能是错的?

    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();
    
    
                }
    
            }
        }
    
        }
    
    
    

2 个答案:

答案 0 :(得分:0)

我已经设法通过等待2秒然后运行任务来解决它。使用this解决方案,它工作。我不得不等待互联网连接准备好了!

答案 1 :(得分:0)

由于等待2秒已经解决了您的问题,因此在建立连接(如DHCP提供您的电话IP并建立路由)之前,可能是Wifi广播来得太早,因为MQTT连接并将数据包发布到妥善交付。

但如果其他一些用户需要等待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);