Android Studio - MQTT not connecting

自作多情 提交于 2019-12-18 05:13:27

问题


I have just started learning using MQTT protocol with Android Studio. Using mosquitto broker, I am able to exchange messages between pub/sub windows. But when I send message to broker through android studio, the app builds successfully but nothing displays on broker's end & system prints Connection Failure. The same code works fine on eclipse java application, but not working on android although required libraries and dependencies have been added.

Please help, what am I missing in this basic step so i can learn forward. Thank you!

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) {

        }


    }
    }

回答1:


Ok so you need two libraries to use MQTT in Android. One is the mqtt paho client and other being Android service library.

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

Then, use MqttAndroidClient instead of MqttClient.

So do new MqttAndroidClient(...).

I posted a full Android MQTT service example here, if that helps.

EDIT: full activity example

(1) MemoryPersistence added when creating new MqttAndroidClient.
(2) Two parameters added to .connect() method of the MqttAndroidClient (mqttConnectOptions and null).
(3) Also, printing the error on 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());
        }
    }
}



回答2:


I wanted to just add a comment, but my rep is too low...so i'm posting it as an answer.

You said you got everything working but are unable to connect because of the IllegalArgumentException. I had the same problem and found out that you need to define the protocol also. So instead of "192.168.0.103:1883" try:

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

From what i read you already did the other necessary steps, but for the sake of giving a complete answer:

  1. Edit the AndroidManifest.xml to include:

    • <service android:name="org.eclipse.paho.android.service.MqttService" /> (from inside the application tag)

    • <uses-permission android:name="android.permission.INTERNET" />

    • <uses-permission android:name="android.permission.WAKE_LOCK" />
    • <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    • <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  2. Edit the build.gradle to include (in the dependencies section):

    • 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. Use the MqttAndroidClient (not the MqttClient)

  4. Put your code in the "onSuccess" callback, to avoid any problems due to the methods being asynchronous (as shown by THEPATEL's answer):

    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:


I had the same issue with MQTT publisher from an android device. While referring to tcp://localhost:1883 from an android emulator, I had to use http://10.0.2.2:1883 since emulator runs on its own VM and localhost would be emulators own loopback address.




回答4:


I was getting Same Error but I have solved it. This is working code.

in 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'

In Manifest :

  <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 Tag inside Application:

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

Activity Code :

 MqttAndroidClient client;
 Button btnsub,btnpublish;

to connect with Mqtt client:

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

To SubScribe on button click :

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

to Publish on button click :

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


来源:https://stackoverflow.com/questions/43038597/android-studio-mqtt-not-connecting

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!