Android MQTT使用详解

MQTT是一个轻量级的消息发布/订阅协议,它是实现基于手机客户端的消息推送服务器的理想解决方案。

首先是配置Android端的依赖

dependencies{
    compile 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
}

添加权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

注册Service:

<service android:name=".MqttMsgService"/>

Android 端代码MqttMsgService实现:

public class MqttMsgService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("MqttMsgService 创建了");
        EventBus.getDefault().register(this);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("MqttMsgService 启动了");
        //启动线程连接mqtt
        new Thread(new Runnable() {
            @Override
            public void run() {
                connectMqtt();
            }
        }).start();
        return START_NOT_STICKY;
    }

    /**
     * 订阅mqtt
     */
    private void connectMqtt() {
    //mqtt管理类用来管理mqtt连接
        MqttManager.getInstance(this).createConnect(Network.BASE_MQTT_URL, Network.BASE_MQTT_USENAME, Network.BASE_MQTT_PASSWORD);
        MqttUtils.online(getApplicationContext());
        threadHeartbat = new MqttMsgService.HeartbeatThread();
        Thread thread = new Thread(threadHeartbat);
        thread.start();
    }
}

    //使用eventbus接收mqtt回传的消息(这个可以自行选择)   
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onInviteMsg(JSONObject jsonObject) {
        Log.e("mq", "mq 收到消息" + jsonObject.toString());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("MqttMsgService 退出了");

        MqttManager.getInstance(this).close();
        EventBus.getDefault().unregister(this);
    }

Android 端代码MqttManager的实现:


public class MqttManager {
    // 单例
    private static MqttManager mInstance = null;
    // 回调
    private MqttCallback mCallback;
    private MqttClient client;
    private MqttConnectOptions conOpt;
    private static String host = "http//:xxxxxxx.xxx.com";

    private static String userName = null;
    private static String password = null;

    private static int qas[];
    private Context context;

    private MqttManager(Context context) {
        mCallback = new MqttCallbackBus(context);
        this.context = context;
    }

    public static MqttManager getInstance(Context context) {
        if (null == mInstance) {
            mInstance = new MqttManager(context);
        }
        return mInstance;
    }

    /**
     * 释放单例, 及其所引用的资源
     */
    public static void release() {
        try {
            if (mInstance != null) {
                mInstance.disConnect();
                mInstance = null;
            }
        } catch (Exception e) {

        }
    }

    /**
     * 创建Mqtt 连接
     *
     * @param brokerUrl Mqtt服务器地址(tcp://xxxx:1863)
     * @param userName  用户名
     * @param password  密码
     * @return
     */
    public boolean createConnect(String brokerUrl, String userName, String password) {

        this.userName = userName;
        this.password = password;
        topics = new String[]{"xxx", "xxx2"};   //注册xxx,xxx2主题,邀请
        qas = new int[]{1, 1};
        //设备唯一识别号
        String deviceId = AndroidUtil.getDeviceID(context);

        if (client != null && client.isConnected()) {
            return true;
        }
        boolean flag = false;
        String tmpDir = System.getProperty("java.io.tmpdir");
        MqttDefaultFilePersistence dataStore = new MqttDefaultFilePersistence(tmpDir);

        try {
            // Construct the connection options object that contains connection parameters
            // such as cleanSession and LWT
            conOpt = new MqttConnectOptions();
            conOpt.setCleanSession(true);
            conOpt.setKeepAliveInterval(20);
            if (password != null) {
                conOpt.setPassword(password.toCharArray());
            }
            if (userName != null) {
                conOpt.setUserName(userName);
            }

            client = new MqttClient(brokerUrl, deviceId, dataStore);
            // Set this wrapper as the callback handler
            client.setCallback(mCallback);
            flag = doConnect();
            client.subscribe(topics, qas);
        } catch (MqttException e) {
            Log.e("mq : " + e.getMessage());
        }

        return flag;
    }

    /**
     * 建立连接
     *
     * @return
     */
    private boolean doConnect() {
        boolean flag = false;
        if (client != null) {
            try {
                client.connect(conOpt);
                Log.e("mq  to " + client.getServerURI() + " with client ID " + client.getClientId());
                flag = true;
            } catch (Exception e) {
                Log.e("mq " + e.toString());
                e.printStackTrace();
            }
        }
        return flag;
    }

    /**
     * Publish / send a message to an MQTT server
     *
     * @param topicName the name of the topic to publish to
     * @param qos       the quality of service to delivery the message at (0,1,2)
     * @param payload   the set of bytes to send to the MQTT server
     * @return boolean
     */
    public boolean publish(String topicName, int qos, byte[] payload) {

        boolean flag = false;


        try {

            if (client == null) {

                createConnect(host, userName, password);
            }

            if (!client.isConnected()) {

                this.reconnect();
            }

            // Create and configure a message
            MqttMessage message = new MqttMessage(payload);
            message.setQos(qos);

            client.publish(topicName, message);
            flag = true;
        } catch (MqttException e) {

            Log.e("mq", e.toString());
        }
        return flag;
    }

   /**
     * Subscribe to a topic on an MQTT server
     * Once subscribed this method waits for the messages to arrive from the server
     * that match the subscription. It continues listening for messages until the enter key is
     * pressed.
     *
     * @param topicName to subscribe to (can be wild carded)
     * @param qos       the maximum quality of service to receive messages at for this subscription
     * @return boolean
     */
    private boolean subscribe(String topicName, int qos) {

        boolean flag = false;

        if (client != null && client.isConnected()) {
            // Subscribe to the requested topic
            // The QoS specified is the maximum level that messages will be sent to the client at.
            // For instance if QoS 1 is specified, any messages originally published at QoS 2 will
            // be downgraded to 1 when delivering to the client but messages published at 1 and 0
            // will be received at the same level they were published at.
            Log.d("Subscribing to topic \"" + topicName + "\" qas " + qos);
            try {
                client.subscribe(topicName, qos);
                flag = true;
            } catch (MqttException e) {

            }
        }

        return flag;
    }

    private boolean subscribe(String[] topicName, int qos[]) {

        boolean flag = false;

        if (client != null && client.isConnected()) {

            try {
                client.subscribe(topicName, qos);
                flag = true;
            } catch (MqttException e) {

                SaveLogUtils.saveInfo("mq subscribe error " + e.toString());

            }
        } else {

            SaveLogUtils.saveInfo("mq subscribe error connect fail ");
        }

        return flag;
    }


    /**
     * 取消连接
     *
     * @throws MqttException
     */
    public void disConnect() throws MqttException {
        if (client != null && client.isConnected()) {
            client.disconnect();
        }
    }

    public void close() {
        if (client != null && client.isConnected()) {
            try {
                client.disconnect();
            } catch (MqttException e) {
                Log.e("mq " + e.toString());
                e.printStackTrace();
            }
        }
    }

    public void reconnect() {

        if (client != null && !client.isConnected()) {

            SaveLogUtils.saveInfo("mq reconnect");
            try {
                client.setCallback(mCallback);
                client.connect(conOpt);
                client.subscribe(topics, qas);
//                MqttUtils.online(this.context);
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }
    }


}

Android 端代码MqttCallbackBus的实现:

public class MqttCallbackBus implements MqttCallback {

    private Context mContext;

    public MqttCallbackBus(Context mContext) {
        this.mContext = mContext;
    }

    @Override
    public void connectionLost(Throwable cause) {
        Log.e(cause.getMessage());
        EventBus.getDefault().post("连接中断");
    }

    @Override
    public void messageArrived(String topic, MqttMessage message) {
        Log.d(topic + "====" + message.toString());

        if (!message.isRetained()) {
            if (topic.equals("xxx")) {

                Map<String, String> msgMap = new HashMap<>();
                msgMap.put("topic", MqttMsgService.OTHER_LOGIN);
                msgMap.put("msg", message.toString());

                EventBus.getDefault().post(msgMap);//收到xxx的消息
            }
            if (topic.equals("xxx2")) {
                JSONObject jsonObject = null;
                try {
                    jsonObject = new JSONObject(message.toString());
                    EventBus.getDefault().post(jsonObject);//收到xxx2的消息
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        } else {
            Log.e("收到老消息", "。。。。。");
        }
    }

}

这样就简单的完成了MQTT了

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值