Cypher236 Cypher236 - 7 months ago 120
Java Question

My code to receive messages from MQTT isn't working?

So in my Android App I've written some code to subscribe to MQTT and (for now) just output the messages it receives. However it isn't working and I'm not sure why, here is my code:

public class MainActivity extends AppCompatActivity implements MqttCallback{
private MqttClient client;
private String clientId = MqttClient.generateClientId();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button myButton = (Button) findViewById(R.id.button);


if (myButton != null) {
myButton.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View view) {
doDemo();
}
});
}
}

public void doDemo() {
try {
client = new MqttClient("tcp://test.mosquitto.org:1883", clientId);
client.connect();
client.setCallback(this);
client.subscribe("IoTLuxSpotifyHaiss");
Toast.makeText(MainActivity.this, "Success!", Toast.LENGTH_LONG).show();
} catch (MqttException e) {
e.printStackTrace();
}
}

@Override
public void connectionLost(Throwable cause) {
// TODO Auto-generated method stub

}

@Override
public void messageArrived(String topic, MqttMessage message)
throws Exception {
System.out.println(message);
}

@Override
public void deliveryComplete(IMqttDeliveryToken token) {
// TODO Auto-generated method stub
}
}


So I wanted it to subscribe to the MQTT topic once I press the button and I added a toast just to help me test it. However it doesn't seem to work and the toast notification never displays. Anyone able to point out where I went wrong?

Thanks.

Edit: Here is the logcat message when I press the button:

05-01 15:04:41.702 14861-14861/com.example.haiss.iotcounterpart W/System.err: MqttException (0)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence.open(MqttDefaultFilePersistence.java:80)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at org.eclipse.paho.client.mqttv3.MqttAsyncClient.<init>(MqttAsyncClient.java:286)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at org.eclipse.paho.client.mqttv3.MqttAsyncClient.<init>(MqttAsyncClient.java:167)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at org.eclipse.paho.client.mqttv3.MqttClient.<init>(MqttClient.java:224)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at org.eclipse.paho.client.mqttv3.MqttClient.<init>(MqttClient.java:136)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at com.example.haiss.iotcounterpart.MainActivity.doDemo(MainActivity.java:38)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at com.example.haiss.iotcounterpart.MainActivity$1.onClick(MainActivity.java:30)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at android.view.View.performClick(View.java:5204)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at android.view.View$PerformClick.run(View.java:21153)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at android.os.Looper.loop(Looper.java:148)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at java.lang.reflect.Method.invoke(Native Method)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
05-01 15:04:41.703 14861-14861/com.example.haiss.iotcounterpart W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

Answer

OK, so were not even getting to the network on main thread problem...

The error is because the MQTT client code is trying to open a file on the local storage to store messages in when publishing at high (1/2) QOS levels. There will be 2 causes for the error:

  1. You may not have granted storage access to the application
  2. You are unlikely to have permission to write to the default location that the MQTT client chooses.

The easiest way to get round this is to use the in memory storage (org.eclipse.paho.client.mqttv3.persist.MemoryPersistence) for the MQTT client.

...
MemoryPersistence persistence = new MemoryPersistence();
client = new MqttClient("tcp://test.mosquitto.org:1883", clientId);
...

Once you get round that problem you are likely to run into the issue of doing network io on the UI thread. To avoid that I suggest you look at the AsyncTask code that Android provides

Comments