场景
Windows上Mqtt服务器搭建与使用客户端工具MqttBox进行测试:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/112305328
SpringBoot整合MQTT服务器实现消息的发送与订阅(推送消息与接收推送):
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/112394731
在上面实现了将MQTT服务器搭建成功并且在SpringBoot中实现消息的发送与订阅。
那么在Android中怎样实现消息的发布。
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
首先你需要将MQTT服务器搭建好,参照上面的博客。
然后新建一个Android项目,在build.gradle中引入mqtt依赖
//mqtt
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.xml中添加网络权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
在项目包下新建一个mqtt包,然后新建一个service叫MQTTService用来实现项目启动后连接到mqtt服务器的一些初始化操作
package com.badao.androidmqttpublishclient.mqtt;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
public class MQTTService extends Service {
private static final String TAG = "MQTTService";
public static final String BROKER_URL = "tcp://你自己的MQTT服务器的ip:1883";
public static final String CLIENT_ID = "gongzhonghaobadaodecehngxvyuan";
public static MqttClient mqttClient;
//mqtt连接配置
private MqttConnectOptions mqttOptions;
private String username = "admin";
private String password = "admin";
public MQTTService() {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand: begin");
try {
//第三个参数代表持久化客户端,如果为null,则不持久化
mqttClient = new MqttClient(BROKER_URL, CLIENT_ID, new MemoryPersistence());
//mqtt连接设置
mqttOptions = new MqttConnectOptions();
mqttOptions.setUserName(username);
mqttOptions.setPassword(password.toCharArray());
//超时连接,单位为秒
mqttOptions.setConnectionTimeout(10);
mqttOptions.setKeepAliveInterval(20);
//false代表可以接受离线消息
mqttOptions.setCleanSession(false);
mqttOptions.setAutomaticReconnect(true);
// 设置回调
mqttClient.setCallback(new PushCallback(mqttClient));
Log.i(TAG, "onStartCommand: before connect");
//客户端下线,其它客户端或者自己再次上线可以接收"遗嘱"消息
// MqttTopic topic1 = mqttClient.getTopic(TOPIC);
// mqttOptions.setWill(topic1, "close".getBytes(), 2, true);
mqttClient.connect(mqttOptions);
Log.i(TAG, "onStartCommand: after connect");
Log.i(TAG, "连接mqtt服务器成功,可以进行发布消息");
} catch (MqttException e) {
e.printStackTrace();
Log.i(TAG, e.getMessage());
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
try {
mqttClient.disconnect();
} catch (MqttException e) {
e.printStackTrace();
}
}
}
注意这里的mqtt服务器的url改为你自己的ip和端口号,以及自己的用户名和密码,获取方式可以参照上面博客。
新建完service后要在AndroidManifest中声明service
<service
android:name=".mqtt.MQTTService"
android:enabled="true"
android:exported="true">
</service>
在service中设置了回调方法,用来处理形如连接成功、收到消息、发送消息成功等的回调。
所以需要新建一个回调方法类PushCallback
package com.badao.androidmqttpublishclient.mqtt;
import android.util.Log;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
public class PushCallback implements MqttCallbackExtended {
private static final String TAG = "PusherCallback";
private MqttClient mqttClient = null;
public PushCallback(MqttClient client) {
mqttClient = client;
}
@Override
public void connectionLost(Throwable cause) {
Log.i(TAG, "连接失败");
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
String msg = new String(message.getPayload());
Log.i(TAG, "消息到达,message: " + msg);
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
Log.i(TAG, "消息成功发送");
}
@Override
public void connectComplete(boolean reconnect, String serverURI) {
Log.i(TAG, "连接完成");
}
}
根据自己的需要重写一些回调方法。
然后就是在MainActivity中的onCreate方法中启动服务,用来在启动后实现连接到mqtt服务器等操作。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//启动服务
Intent intent = new Intent(this, MQTTService.class);
startService(intent);
}
为了实现推送消息,在主页面添加一个按钮
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/publishButton"
android:text="发布消息"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
然后在activity中设置按钮的点击事件
Button publishButton = findViewById(R.id.publishButton);
publishButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//在mqtt中用QoS来标识服务质量
//QoS=0时,报文最多发送一次,有可能丢失
//QoS=1时,报文至少发送一次,有可能重复
//QoS=2时,报文只发送一次,并且确保消息只到达一次。
MqttMessage mqttMessage = new MqttMessage();
mqttMessage.setId((int) Math.random());
mqttMessage.setQos(1);
mqttMessage.setPayload("这是来自APP发布的消息:公众号-霸道的程序猿".getBytes());
/*当设置Retain标识位的时候,该消息即为遗言消息。
broker收到该消息后会保存此消息,当有新的订阅者订阅此主题时候,broker会立即发送此消息。
有点类似于会话清除,不同的是遗言只有一条,后面的遗言消息会覆盖前面的。
如果需要删除retain消息,可以发布一个空的retain消息,因为每个新的retain消息都会覆盖最后一个retain消息*/
mqttMessage.setRetained(false);
try {
MQTTService.mqttClient.publish("badaodechengxvyuan",mqttMessage);
} catch (MqttException e) {
e.printStackTrace();
}
}
});
在点击事件中,构造一个MqttMessage消息对象,设置其相关参数,主要是通过器payload设置其消息内容。
然后调用service的mqtt客户端的publish方法,第一个参数是主题,第二个参数是消息对象。
然后运行app
可以看到service已经启动成功,并且调用了连接成功的回调方法
然后为了收到想通主题的订阅的消息,使用MQTTBox订阅一个同样主题
然后在点击主页面的发布消息的按钮,可以看到发送成功的回调方法已经被调用
然后在Mqttbox中也已经收到了消息
示例代码下载
https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/14093918
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/136426.html