Android中连接MQTT服务器实现发布一个消息推送给订阅者(附代码下载)

场景

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

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

霸道流氓气质

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值