I'd like to publish messages from an android service
to a local server. Here is parts of my code in the simplest form based on snippets from here.
MemoryPersistence memPer;
MqttAndroidClient client;
@Override
public IBinder onBind(Intent intent) {
memPer = new MemoryPersistence();
client = new MqttAndroidClient(this, "tcp://192.168.1.42:1883", "clientid", memPer);
try {
client.connect(null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken mqttToken) {
Log.i("MQTT", "Client connected");
Log.i("MQTT", "Topics=" + mqttToken.getTopics());
MqttMessage message = new MqttMessage("Hello, I am Android Mqtt Client.".getBytes());
message.setQos(2);
message.setRetained(false);
try {
client.publish("messages", message);
Log.i("MQTT", "Message published");
client.disconnect();
Log.i("MQTT", "client disconnected");
} catch (MqttPersistenceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MqttException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onFailure(IMqttToken arg0, Throwable arg1) {
// TODO Auto-generated method stub
Log.i("MQTT", "Client connection failed: " + arg1.getMessage());
}
});
} catch (MqttException e) {
e.printStackTrace();
}
return mBinder;
}
But the onFailure function is always called and I get the error:
I/MQTT﹕ Client connection failed: cannot start service org.eclipse.paho.android.service.MqttService
Apparently returned by the library because 'listener != null', Line 410. Using the debugger, it shows that 'listener = SensorLoggerService$1@3634'. SensorLoggerService is my service.
Any idea what could be going wrong? Thanks a lot.
The same issue for me; in my case, the problem was that the <service>
tag was outside the <application>
tag.
In the beginning I had this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.myapp" >
...
<service android:name="org.eclipse.paho.android.service.MqttService">
</service>
...
<application
android:name="com.mycompany.myapp" ... >
...
</application>
Then I changed to this:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.myapp" >
...
<application
android:name="com.mycompany.myapp" ... >
...
<service android:name="org.eclipse.paho.android.service.MqttService">
</service>
</application>
And everything worked!
You need also to add the INTERNET
, ACCESS_NETWORK_STATE
and WAKE_LOCK
permissions.
HTH
After few hours of trying everything, I managed to connect with MqttClient
instead of MqttAndroidClient
. I still don't know why the MqttAndroidClient
was failing.
Here are some tips:
The service class should implement MqttCallback
The manifest (`AndroidManifest.xml') must contain at least the following:
<!-- Internet permission -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- MqttService -->
<service android:name="org.eclipse.paho.android.service.MqttService" />
The modified code:
MemoryPersistence memPer;
MqttClient client;
@Override
public IBinder onBind(Intent intent) {
memPer = new MemoryPersistence();
try
{
client = new MqttClient("tcp://192.168.1.42:1883", MqttClient.generateClientId(), null);
client.setCallback(this);
}
catch (MqttException e1)
{
e1.printStackTrace();
}
MqttConnectOptions options = new MqttConnectOptions();
try
{
client.connect(options);
}
catch (MqttException e)
{
Log.d(getClass().getCanonicalName(), "Connection attempt failed with reason code = " + e.getReasonCode() + ":" + e.getCause());
}
// Now, try to publish a message
String msg = "Hello, I am Android Mqtt Client.";
try
{
MqttMessage message = new MqttMessage();
message.setQos(1);
message.setPayload(msg.getBytes());
client.publish("sensors/test", message);
}
catch (MqttException e)
{
Log.d(getClass().getCanonicalName(), "Publish failed with reason code = " + e.getReasonCode());
}
return mBinder;
}
@Override
public void connectionLost(Throwable cause)
{
Log.d("MQTT", "MQTT Server connection lost" + cause.getMessage());
}
@Override
public void messageArrived(String topic, MqttMessage message)
{
Log.d("MQTT", "Message arrived:" + topic + ":" + message.toString());
}
@Override
public void deliveryComplete(IMqttDeliveryToken token)
{
Log.d("MQTT", "Delivery complete");
}
For more details, refer to this nice guide: https://developer.motorolasolutions.com/docs/DOC-2315
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With