问题描述
当您第一次打开应用程序时,我想要一个屏幕,您可以在其中输入经纪人信息并单击尝试并保存.
When you first open the app I want a screen where you can enter the broker information and click try and save.
当点击尝试时,它应该只显示一个 Snackbar
说明该信息是否有助于成功连接.
When clicking try it should just show a Snackbar
saying if the information makes for a successful connection.
这是我按下 try 按钮时调用的代码:
This is the code I call when the try button is pressed:
private void tryConnection(View v){
if(verifyInputs()){
Snackbar.make(v, getString(R.string.trying_connection), Snackbar.LENGTH_LONG).show();
String clientId = MqttClient.generateClientId();
MqttAndroidClient client =
new MqttAndroidClient(this.getApplicationContext(), getServerAddress(),
clientId);
try {
IMqttToken token = client.connect();
final View vinner = v;
token.setActionCallback(new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
// We are connected
Snackbar.make(vinner, "Success", Snackbar.LENGTH_LONG).show();
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
// Something went wrong e.g. connection timeout or firewall problems
Snackbar.make(vinner, "Fail", Snackbar.LENGTH_LONG).show();
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
}
问题是,onFailure
似乎在无法连接到服务器时没有被调用,而是在与服务器的连接丢失时调用.
The problem is, onFailure
doesn't seem to be called when it cannot connect to the server, but when a connection to a server is lost.
如何测试连接,以便存储它并返回到主要活动?
How do I just test the connection, so I can store it and go back to the main activity?
推荐答案
好的,所以我看不到您的完整服务、任何其他实现或您如何/在何处使用它,所以我提供了我的 MQTT 示例服务.
Ok, so I can't see your full service, any other implementation or how/where you are using this so I'm providing a sample of my MQTT service.
也许你可以比较一下,发现任何问题并修复它.
Maybe you can compare it, find any issue and fix it.
或者你可以使用我的实现.由你决定.希望对您有所帮助.
Or you can just use my implementation. Up to you. Hope it helps.
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.util.Log;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import java.util.ArrayList;
public class MyMqttService extends Service implements MqttCallback, IMqttActionListener {
private final IBinder binder = new MyBinder();
private MqttAndroidClient mqttClient;
private MqttConnectOptions mqttConnectOptions;
private static final MemoryPersistence persistence = new MemoryPersistence();
private ArrayList<MqttAndroidClient> lostConnectionClients;
private String clientId = "";
private boolean isReady = false;
private boolean doConnectTask = true;
private boolean isConnectInvoked = false;
private Handler handler = new Handler();
private final int RECONNECT_INTERVAL = 10000; // 10 seconds
private final int DISCONNECT_INTERVAL = 20000; // 20 seconds
private final int CONNECTION_TIMEOUT = 60;
private final int KEEP_ALIVE_INTERVAL = 200;
private String broker_url = "my_broker";
public MyMqttService() {}
public class MyBinder extends Binder {
public MyMqttService getService() {
return MyMqttService.this;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCreate() {
super.onCreate();
initMqttClient();
}
@Override
public void onDestroy() {
super.onDestroy();
disconnectClients();
if (isConnectInvoked && mqttClient != null && mqttClient.isConnected()) {
try {
// unsubscribe here
unsubscribe("¯\_(ツ)_/¯");
mqttClient.disconnect();
} catch (MqttException e) {
Log.e("TAG", e.toString());
}
}
handler.removeCallbacks(connect);
handler.removeCallbacks(disconnect);
}
private void initMqttClient() {
if(mqttClient != null) {
mqttClient = null;
}
lostConnectionClients = new ArrayList<>();
mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setCleanSession(true);
mqttConnectOptions.setConnectionTimeout(CONNECTION_TIMEOUT);
mqttConnectOptions.setKeepAliveInterval(KEEP_ALIVE_INTERVAL);
setNewMqttClient();
handler.post(connect);
handler.postDelayed(disconnect, DISCONNECT_INTERVAL);
}
private void setNewMqttClient() {
mqttClient = new MqttAndroidClient(MyMqttService.this, broker_url, clientId, persistence);
mqttClient.setCallback(this);
}
public Runnable connect = new Runnable() {
public void run() {
connectClient();
handler.postDelayed(connect, RECONNECT_INTERVAL);
}
};
public Runnable disconnect = new Runnable() {
public void run() {
disconnectClients();
handler.postDelayed(disconnect, DISCONNECT_INTERVAL);
}
};
private void connectClient() {
if(doConnectTask) {
doConnectTask = false;
try {
isConnectInvoked = true;
mqttClient.connect(mqttConnectOptions, null, this);
} catch (MqttException ex) {
doConnectTask = true;
Log.e("TAG", ex.toString());
}
}
}
private void disconnectClients() {
if (lostConnectionClients.size() > 0) {
// Disconnect lost connection clients
for (MqttAndroidClient client : lostConnectionClients) {
if (client.isConnected()) {
try {
client.disconnect();
} catch (MqttException e) {
Log.e("TAG", e.toString());
}
}
}
// Close already disconnected clients
for (int i = lostConnectionClients.size() - 1; i >= 0; i--) {
try {
if (!lostConnectionClients.get(i).isConnected()) {
MqttAndroidClient client = lostConnectionClients.get(i);
client.close();
lostConnectionClients.remove(i);
}
} catch (IndexOutOfBoundsException e) {
Log.e("TAG", e.toString());
}
}
}
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.e("TAG", "deliveryComplete()");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String payload = new String(message.getPayload());
// do something
}
@Override
public void connectionLost(Throwable cause) {
Log.e("TAG", cause.getMessage());
}
@Override
public void onSuccess(IMqttToken iMqttToken) {
isReady = true;
// subscribe here
subscribe("¯\_(ツ)_/¯");
}
@Override
public void onFailure(IMqttToken iMqttToken, Throwable throwable) {
setNewMqttClient();
isReady = false;
doConnectTask = true;
isConnectInvoked = false;
}
private void subscribe(String topic) {
try {
mqttClient.subscribe(topic, 0);
isReady = true;
} catch (MqttSecurityException mqttSexEx) {
isReady = false;
} catch (MqttException mqttEx) {
isReady = false;
}
}
private void unsubscribe(String topic) {
try {
mqttClient.unsubscribe(topic);
} catch (MqttSecurityException mqttSecEx) {
Log.e("TAG", mqttSecEx.getMessage());
} catch (MqttException mqttEx) {
Log.e("TAG", mqttEx.getMessage());
}
}
private void publish(String topic, String jsonPayload) {
if(!isReady) {
return;
}
try {
MqttMessage msg = new MqttMessage();
msg.setQos(0);
msg.setPayload(jsonPayload.getBytes("UTF-8"));
mqttClient.publish(topic, msg);
} catch (Exception ex) {
Log.e("TAG", ex.toString());
}
}
}
我的另一个建议是设置本地广播,这样当您的活动加载并启动服务时,如果 MQTT 服务能够连接,您发送一个广播说已连接并显示一个 Snackbar
.如果连接失败,您将发送不同的广播并显示不同的消息.
My other suggestion would be to just setup local broadcast so when your activity loads and you start the service, if MQTT service is able to connect, you send a broadcast saying connected and you show a Snackbar
. If connection failed, you send a different broadcast and show a different message.
这篇关于使用 Paho MqttClient 在 Android 上尝试 Mqtt 连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!