【问题标题】:Android Studio - MQTT not connectingAndroid Studio - MQTT 未连接
【发布时间】:2017-03-27 05:33:35
【问题描述】:

我刚刚开始学习在 Android Studio 中使用 MQTT 协议。使用 mosquitto 代理,我能够在 pub/sub 窗口之间交换消息。但是当我通过 android studio 向代理发送消息时,应用程序构建成功,但代理端没有显示任何内容,并且系统打印连接失败。相同的代码在 eclipse java 应用程序上运行良好,但在 android 上无法运行,尽管已添加所需的库和依赖项。

请帮忙,我在这个基本步骤中缺少什么,以便我可以继续学习。谢谢!

app-build.gradle

    dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.2.0'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'

// have added following dependencies

    provided 'com.google.android.things:androidthings:0.2-devpreview'
    provided 'com.google.android.things:androidthings:0.1-devpreview'
    compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2'

}

project-build.gradle

   repositories {
            jcenter()
            maven {
                url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
            }    
}

AndroidManifest.xml

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.zoha.mqttandroidiot">

    <!-- Permissions the Application Requires -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">


        <activity android:name=".HomeActivity">

            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>

            <!-- Launch activity automatically on boot -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.IOT_LAUNCHER"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>

        </activity>
<service android:name="org.eclipse.paho.android.service.MqttService"/>

    </application>

</manifest>

HomeActivity

  public class HomeActivity extends AppCompatActivity{

    MqttAndroidClient client;
   // private static final MemoryPersistence persistence = new MemoryPersistence();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://localhost:1883", "androidSampleClient");
        mqttAndroidClient.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable cause) {
                System.out.println("Connection was lost!");

            }

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                System.out.println("Message Arrived!: " + topic + ": " + new String(message.getPayload()));

            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
                System.out.println("Delivery Complete!");
            }
        });

        try {
            mqttAndroidClient.connect(null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    System.out.println("Connection Success!");
                    try {
                        System.out.println("Subscribing to /test");
                        mqttAndroidClient.subscribe("/test", 0);
                        System.out.println("Subscribed to /test");
                        System.out.println("Publishing message..");
                        mqttAndroidClient.publish("/test", new MqttMessage("Hello world testing..!".getBytes()));
                    } catch (MqttException ex) {

                    }

                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    System.out.println("Connection Failure!");
                }
            });
        } catch (MqttException ex) {

        }


    }
    }

【问题讨论】:

  • 另外,请确保修复 AndroidManifest.xml 文件中的 service 标签。 service.. 标签应该在你的 activity 标签之外。所以复制‹service.. 行并将其粘贴到&lt;/activity&gt; 行下方
  • 将BROKER url更改为您的系统IP地址而不是您的手机IP。

标签: android android-studio mqtt iot mosquitto


【解决方案1】:

好的,所以您需要两个库才能在 Android 中使用 MQTT。一个是 mqtt paho 客户端,另一个是 Android 服务库。

compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.0.2'
compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.0.2'

然后,使用MqttAndroidClient 而不是MqttClient

new MqttAndroidClient(...)也是如此。

我发布了一个完整的 Android MQTT 服务示例 here,如果有帮助的话。

编辑:完整活动示例

(1) MemoryPersistence 在创建新的MqttAndroidClient 时添加。
(2)MqttAndroidClient.connect()方法增加了两个参数(mqttConnectOptionsnull)。
(3) 另外,在onFailure()上打印错误

public class HomeActivity extends AppCompatActivity {

    private MqttAndroidClient client;
    private final MemoryPersistence persistence = new MemoryPersistence();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final MqttAndroidClient mqttAndroidClient = new MqttAndroidClient(this.getApplicationContext(), "tcp://localhost:1883", "androidSampleClient", persistence);
        mqttAndroidClient.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable cause) {
                System.out.println("Connection was lost!");
            }

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                System.out.println("Message Arrived!: " + topic + ": " + new String(message.getPayload()));
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
                System.out.println("Delivery Complete!");
            }
        });

        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setCleanSession(true);

        try {
            mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
                @Override
                public void onSuccess(IMqttToken asyncActionToken) {
                    System.out.println("Connection Success!");
                    try {
                        System.out.println("Subscribing to /test");
                        mqttAndroidClient.subscribe("/test", 0);
                        System.out.println("Subscribed to /test");
                        System.out.println("Publishing message..");
                        mqttAndroidClient.publish("/test", new MqttMessage("Hello world testing..!".getBytes()));
                    } catch (MqttException ex) {

                    }
                }

                @Override
                public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                    System.out.println("Connection Failure!");
                    System.out.println("throwable: " + exception.toString());
                }
            });
        } catch (MqttException ex) {
            System.out.println(ex.toString());
        }
    }
}

【讨论】:

  • 感谢您的帮助。但现在它在发布语句上给出空指针异常:'org.eclipse.paho.client.mqttv3.IMqttDeliveryToken org.eclipse.paho.android.service.MqttService.publish(java.lang.String, java.lang.String, org .eclipse.paho.client.mqttv3.MqttMessage, java.lang.String, java.lang.String)' 在空对象引用上
  • @Noor 你能调试并找出哪个参数为空吗?如果有的话,只需尝试打印日志中的每个参数,看看哪个为空。我似乎是一个很简单的问题
  • @th3pat3I 你能看看修改后的代码吗?它现在没有给出错误,但显示连接失败。
  • @Noor 我发布了一个示例。试一试
  • @th3pat3I 非常感谢您的快速回复。对于您的示例,连接失败并显示以下消息:无法连接到服务器 (32103) - java.net.connectException: failed to connect to localhost/127.0.0.1(port 1883) after 3000ms: isConnected failed: ECONNREFUSED (connection denied) ) .我还尝试了“192.168.0.103:1883”作为代理地址,这是我的电脑的 IP 地址,然后它给出了 java.lang.IllegalArgumentException: 192.168.0.103:1883。仍在尝试解决它。​​
【解决方案2】:

我只想添加评论,但我的代表太低了...所以我将其发布为答案。

您说您一切正常,但由于IllegalArgumentException 而无法连接。我遇到了同样的问题,发现您还需要定义协议。 所以不要尝试"192.168.0.103:1883"

String serverURI = "tcp://192.168.0.103:1883"

根据我读到的内容,您已经完成了其他必要的步骤,但为了给出完整的答案:

  1. 编辑AndroidManifest.xml 以包括:

    • &lt;service android:name="org.eclipse.paho.android.service.MqttService" /&gt; (来自application 标签内)

    • &lt;uses-permission android:name="android.permission.INTERNET" /&gt;

    • &lt;uses-permission android:name="android.permission.WAKE_LOCK" /&gt;
    • &lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /&gt;
    • &lt;uses-permission android:name="android.permission.READ_PHONE_STATE" /&gt;
  2. 编辑build.gradle 以包含(在dependencies 部分中):

    • compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.1'

    • compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

  3. 使用MqttAndroidClient(不是MqttClient

  4. 将您的代码放在“onSuccess”回调中,以避免由于方法异步导致的任何问题(如 THEPATEL 的回答所示):

    MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
    mqttConnectOptions.setKeepAliveInterval(60);//seconds
    mqttConnectOptions.setCleanSession(true);
    mqttConnectOptions.setAutomaticReconnect(true);
    
    mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                //Treat success here (subscribe, publish etc)
            }
    
            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                //Treat failure here
            }
        });
    

【讨论】:

    【解决方案3】:

    我在 Android 设备上使用 MQTT 发布者时遇到了同样的问题。在从 android 模拟器中引用 tcp://localhost:1883 时,我不得不使用 http://10.0.2.2:1883,因为模拟器在其自己的 VM 上运行,而 localhost 将是模拟器自己的环回地址。

    【讨论】:

      【解决方案4】:

      我遇到了同样的错误,但我已经解决了。 这是工作代码。

      在 gradle 中:

      compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
          compile 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.0'
      

      在清单中:

        <uses-permission android:name="android.permission.WAKE_LOCK" />
          <uses-permission android:name="android.permission.INTERNET" />
          <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
          <uses-permission android:name="android.permission.READ_PHONE_STATE" />
      

      应用程序内的服务标签:

        <service android:name="org.eclipse.paho.android.service.MqttService" >
              </service>
      

      活动代码:

       MqttAndroidClient client;
       Button btnsub,btnpublish;
      

      连接Mqtt客户端:

      String clientId = MqttClient.generateClientId();
         client = new MqttAndroidClient(getApplicationContext(), "tcp://www.domain.in/ip:11883",clientId);
              client.connect().setActionCallback(new IMqttActionListener() {
                  @Override
                  public void onSuccess(IMqttToken asyncActionToken) {
                      // We are connected
                  }
                  @Override
                  public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                  }
              });
      

      点击按钮订阅:

         client.subscribe("topic", 0, null, new IMqttActionListener() {
                              @Override
                              public void onSuccess(IMqttToken asyncActionToken) {
                              }
                              @Override
                              public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                              }
                          });
                          client.subscribe("topic", 0, new IMqttMessageListener() {
                              @Override
                              public void messageArrived(String topic, MqttMessage message) throws Exception {
                              }
                          });
      

      点击按钮发布:

         MqttMessage message = new MqttMessage();
                          message.setPayload("message".getBytes());
                          client.publish("topic", message);
      

      【讨论】:

        猜你喜欢
        • 2013-09-09
        • 1970-01-01
        • 1970-01-01
        • 2021-10-21
        • 1970-01-01
        • 1970-01-01
        • 2014-08-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多