I'm trying to create an MqttClient in Android, using an Android emulator (Nexus7) on ADT (Eclipse 3.8.0 on a Linux Fedora17. I found this question answered (Android MQTT unable to create client), but it failed to solve my problem.
I created an activity that allows the user to enter the directory where to store the presistence file, but there is no way to avoid catching the exception. I tried with "/mnt/sdcard/", "/mnt/", "/mnt/sdcard/tmp/" and similar.
Do I need to pay attention to particular settings in Android emulator on in Eclipse project? Are there any uses-permissions to be included in the application?
I looked at the various mqtt resources mentioned in the quoted answered question, but I couldn't manage to find an answer.
This is my code:
package com.storassa.android.mqttsample;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttDefaultFilePersistence;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.TextView;
public class MqttSample extends Activity {
Button okButton = null;
AutoCompleteTextView inputTextView = null;
TextView errorTextView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mqtt_sample);
okButton = (Button)findViewById(R.id.okButton);
inputTextView = (AutoCompleteTextView)findViewById(R.id.InputText);
errorTextView = (TextView)findViewById(R.id.errorText);
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
try {
String dir = inputTextView.getText().toString();
MqttDefaultFilePersistence mdfp = new MqttDefaultFilePersistence(
dir);
MqttClient client = new MqttClient("tcp://127.0.0.1:1833",
"0001", mdfp);
}
catch (Exception e) {
String errorText = "";
for (StackTraceElement error : e.getStackTrace())
errorText += error.toString() + "\n";
errorTextView.setText(errorText);
}
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_mqtt_sample, menu);
return true;
}
}
and this is the Stack:
MqttException(0) at
org.eclipse.paho.client.mqttv3.MqttDefaultFilePersistence.open(MqttDefaultFilePersistence.java:74)
org.eclipse.paho.client.mqttv3.MqttClient.<init>(MqttClient.java:183)
com.storassa.android.mqttsample.MqttSample$1.onClick(MqttSample.java:38)
android.view.View.performClick(View.java:4202)
android.view.View$PerformClick.run(View.java:17340)
android.os.Handler.handleCallback(Handler.java:725)
android.os.Handler.dispatchMessage(Handler.java:92)
android.os.Looper.loop(Looper.java:137)
android.app.ActivityThread.main(ActivityThread.java:5039)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:511)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
dalvik.system.NativeStart.main(Native Method)
You could alternatively use an instance of the class MemoryPersistence if you don't rely on file persistency.
So the call to get a client would be:
MemoryPersistence persistence = new MemoryPersistence();
MqttClient client = new MqttClient(host, clientId, persistence);
After a whole day spent in understanding the issue and in googling anywhere to find it, eventually I got it: very simply a permission has to be added to the manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I don't know whether internal directories can be used instead of the sdcard.
As this is the first time I answer my own question, let me know whether it is a good etiquette to flag as correct answer my own answer (I found different opinions on this topics)
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