想要实现app端连接MQTT服务器并实现数据传输
1、build.gradle中引用
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.0' implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
2、AndroidManifest.xml中添加
<service android:name="org.eclipse.paho.android.service.MqttService" />
3、AndroidManifest.xml中添加一些需要的权限,如
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.INTERNET" />
有一点需要注意一下,SDK版本过高的话会造成MQTT无法连接到服务端,第三库使用的不是androidx
以上配置好之后,接下来就可以进一步了,还是直接贴代码吧
1、连接MQTT服务端 public void connectMqttServer() { String mqclientId = "mqttClientId" + System.currentTimeMillis(); mqttAndroidClient = new MqttAndroidClient(mContext, brokerUrl, mqclientId); mqttAndroidClient.setCallback(new MqttCallbackExtended() { @Override public void connectComplete(boolean reconnect, String serverURI) { if (reconnect) { // Because Clean Session is true, we need to re-subscribe } } @Override public void connectionLost(Throwable cause) { } @Override public void messageArrived(String topic, MqttMessage message) throws Exception { } @Override public void deliveryComplete(IMqttDeliveryToken token) { } }); MqttConnectOptions mqttConnectOptions = new MqttConnectOptions(); mqttConnectOptions.setAutomaticReconnect(true); mqttConnectOptions.setCleanSession(false); mqttConnectOptions.setUserName(BaseFileConfig.userName); mqttConnectOptions.setPassword(BaseFileConfig.password.toCharArray()); try { mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { DisconnectedBufferOptions disconnectedBufferOptions = new DisconnectedBufferOptions(); disconnectedBufferOptions.setBufferEnabled(true); disconnectedBufferOptions.setBufferSize(100); disconnectedBufferOptions.setPersistBuffer(false); disconnectedBufferOptions.setDeleteOldestMessages(false); mqttAndroidClient.setBufferOpts(disconnectedBufferOptions); } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { } }); } catch (MqttException ex){ ex.printStackTrace(); } } 上面mqclientId 就是一个随机的字符串,但是要保证唯一性,brokerUrl到时以提供的为准,开头加上tcp://
2、发布消息
public void publishMessage(String publishMsg, String publishTopic){ try { if(mqttAndroidClient != null) { MqttMessage message = new MqttMessage(); message.setQos(1); try { message.setPayload(publishMsg); } catch (Exception e) { e.printStackTrace(); } mqttAndroidClient.publish(publishTopic, message); } } catch (MqttException e) { e.printStackTrace(); } }
publishTopic就是发布的主题,根据实际定义的来;publishMsg就是需要发送的数据内容
3、订阅
protected void subscribeToTopic(String subscriptionTopic){ try { if(mqttAndroidClient == null || !mqttAndroidClient.isConnected()) { return; } mqttAndroidClient.subscribe(subscriptionTopic, 0, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { } }); mqttAndroidClient.subscribe(subscriptionTopic, 0, new IMqttMessageListener() { @Override public void messageArrived(String topic, MqttMessage message) throws Exception { String messageText = new String(message.getPayload(), "GBK"); } }); } catch (MqttException ex){ ex.printStackTrace(); } }
subscriptionTopic就是订阅的主题,根据实际定义的来就好;加上"GBK"编码格式是为了防止接收到的数据中存在中文乱码(若使用的是MQTT.fx加上GBK,若使用的是MQTTX则不需要了)
4、取消订阅
protected void unSubscribeToTopic(String subscriptionTopic){ try { mqttAndroidClient.unsubscribe(subscriptionTopic, null, new IMqttActionListener() { @Override public void onSuccess(IMqttToken asyncActionToken) { } @Override public void onFailure(IMqttToken asyncActionToken, Throwable exception) { } }); } catch (MqttException e) { e.printStackTrace(); } }
5、最后注意使用完后disconnect()
public void disconnectMQTT() { try { if(mqttAndroidClient != null) { mqttAndroidClient.disconnect(); } mqttAndroidClient = null; } catch (MqttException e) { e.printStackTrace(); } }