前言
我們搭建好並測通了MQTT.fx的Broker服務器,現在我們想要用Android客戶點去和服務器通信。
和Android通信有一套已有的庫就是Paho Android Service。
Paho Android Service是一個基於Java語言的Paho MQTT庫開發的MQTT客戶端服務包。
接入
- 在build.gradle中添加倉庫地址
maven {
url "https://repo.eclipse.org/content/repositories/paho-snapshots/"
}
或者是
maven {
url "https://repo.eclipse.org/content/repositories/paho-releases/"
}
- 在App或者是子Module中引入依賴
dependencies {
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
}
- 在AndroidManifest文件中添加權限和註冊Service
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxx.xxxx.mqtt">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application>
<service android:name="org.eclipse.paho.android.service.MqttService" />
</application>
</manifest>
應用
- 以下是建聯和發佈訂閱等代碼
public class IOT {
private final String TAG = "MyIOT";
private Context mContext;
/* 用於上報消息 */
final private String PUB_TOPIC = "/message/publish";
/* 用於接受消息 */
final private String SUB_TOPIC = "/message/publish";
/* 自己部署到本地的服務器地址(協議+地址+端口號) */
private final String HOST = "tcp://替換成自己的IP:1883";
/* 用戶名 */
private String USERNAME = "admin";
/* 密碼 */
private String PASSWORD = "admin";
private MqttAndroidClient mqttAndroidClient;
private static final class IOTHolder {
private static final IOT instance = new IOT();
}
public static IOT getInstance() {
return IOT.IOTHolder.instance;
}
/**
* 初始化
*
* @param context
*/
public void init(Context context) {
mContext = context.getApplicationContext();
connect();
}
/**
* 訂閱特定的主題
*
* @param topic mqtt主題
*/
public void subscribeTopic(String topic) {
try {
mqttAndroidClient.subscribe(topic, 0, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.i(TAG, "subscribed succeed");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.i(TAG, "subscribed failed");
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 向默認的主題/user/update發佈消息
*
* @param payload 消息載荷
*/
public void publishMessage(String payload) {
try {
if (!mqttAndroidClient.isConnected()) {
mqttAndroidClient.connect();
}
MqttMessage message = new MqttMessage();
message.setPayload(payload.getBytes());
message.setQos(0);
mqttAndroidClient.publish(PUB_TOPIC, message, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.i(TAG, "publish succeed!");
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.i(TAG, "publish failed!");
}
});
} catch (MqttException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
/**
* 斷開連接銷燬資源
*/
public void destroy() {
try {
if (mqttAndroidClient.isConnected()) {
mqttAndroidClient.disconnect();
mqttAndroidClient.unregisterResources();
}
mqttAndroidClient = null;
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 斷開連接
*/
public void disconnect() {
try {
if (mqttAndroidClient.isConnected()) {
mqttAndroidClient.disconnect();
}
} catch (MqttException e) {
e.printStackTrace();
}
}
/**
* 重新連接
*/
public void reInit() {
connect();
}
/**
* 連接
*/
private void connect() {
if (mqttAndroidClient != null && mqttAndroidClient.isConnected()) return;
MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
mqttConnectOptions.setUserName(USERNAME);
mqttConnectOptions.setPassword(PASSWORD.toCharArray());
mqttConnectOptions.setCleanSession(false); // 不清理離線消息。qos=1的消息,在設備離線期間會保存在雲端。
mqttConnectOptions.setAutomaticReconnect(false); //本demo關閉自動重連。強烈建議生產環境開啓自動重連。
mqttConnectOptions.setKeepAliveInterval(300);
/* 創建MqttAndroidClient對象, 並設置回調接口 */
mqttAndroidClient = new MqttAndroidClient(mContext, HOST, DeviceUuidFactory2.getDeviceUuidStr(mContext));
mqttAndroidClient.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
Log.i(TAG, "connection lost");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
Log.i(TAG, "topic: " + topic + ", msg: " + new String(message.getPayload()));
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.i(TAG, "msg delivered");
}
});
/* Mqtt建連 */
try {
mqttAndroidClient.connect(mqttConnectOptions, null, new IMqttActionListener() {
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.i(TAG, "connect succeed");
//自動訂閱
subscribeTopic(SUB_TOPIC);
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.i(TAG, "connect failed");
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}