Android mqtt入门 Android studio

分享 mqtt简单使用介绍:

1、as创建工程

2、官网下载mqtt支持包放入lib文件,点击打开链接,https://repo.eclipse.org/content/repositories/paho-releases/org/eclipse/paho/org.eclipse.paho.client.mqttv3/1.2.0/。当前使用的是:

org.eclipse.paho.client.mqttv3-1.2.0.jar

3、然后开始工作:


import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
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.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 全局主服务分发和接收mqtt消息
 */
public class MQTTService extends Service {
    private static final String TAG = "MQTTService";

    public final String SERVICE_CLASSNAME = "de.eclipsemagazin.mqtt.push.MQTTService";

    private Handler handler;

    //    private String host = "tcp://192.168.2.151:1883";
//    private String userName = "admin";
//    private String passWord = "password";
    private int i = 1;
    private static MqttClient client;

    //    private String myTopic = "qaiot/user/f5c71e03-c324-4b32-823c-563471e86da9";
//    private String myTopic = "qaiot/user/f5c71e03-c324-4b32";
    private String myTopic = "qaiot/server/user/1.0/cn";
    String clientId = "qaiot/user/f5c71e03-c324-4b32";

    private MqttConnectOptions options;

    private static ScheduledExecutorService scheduler;

    public JooanMQTTService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        initMqttClient();

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                if (msg.what == 1) {
                    Toast.makeText(JooanApplication.get(), (String) msg.obj, Toast.LENGTH_SHORT).show();

                    NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                    Notification notification = new Notification(R.drawable.menu_item_small_bg, "Mqtt即时推送", System.currentTimeMillis());
//                    notification.contentView = new RemoteViews("com.hxht.testmqttclient", R.layout.activity_notification);
                    notification.contentView = new RemoteViews("com.jooan.qiaoanzhilian", R.layout.service_jooan_mqtt_notification);
                    notification.contentView.setTextViewText(R.id.tv_desc, (String) msg.obj);
                    notification.defaults = Notification.DEFAULT_SOUND;
                    notification.flags = Notification.FLAG_AUTO_CANCEL;
                    manager.notify(i++, notification);

                    Log.e(TAG, "Mqtt收到推送结果: " + (String) msg.obj);
                } else if (msg.what == 2) {
                    Log.i(TAG, "连接成功");
                    Toast.makeText(JooanApplication.get(), "连接成功", Toast.LENGTH_SHORT).show();
                    try {
                        client.subscribe(clientId, 1);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                } else if (msg.what == 3) {
                    Toast.makeText(JooanApplication.get(), "连接失败,系统正在重连", Toast.LENGTH_SHORT).show();
                    Log.i(TAG, "连接失败,系统正在重连");
                }
            }
        };

        startReconnect();
    }


    private void initMqttClient() {
        try {
            //host为主机名,testclientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
            client = new MqttClient(JooanApplication.get().BROKER_URL, myTopic, new MemoryPersistence());
            //MQTT的连接设置
            options = new MqttConnectOptions();
            //设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(true);
            //设置连接的用户名
            options.setUserName(JooanApplication.get().userName);
            //设置连接的密码
            options.setPassword(JooanApplication.get().passWord.toCharArray());
            // 设置超时时间 单位为秒
            options.setConnectionTimeout(10);
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
            options.setKeepAliveInterval(20);
//            options.setWill();//如果项目中需要知道客户端是否掉线可以调用该方法
            //设置回调
            client.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    //连接丢失后,一般在这里面进行重连
                    Log.w(TAG, "connectionLost----------: " + cause.getMessage());
                }

                @Override
                public void messageArrived(String topic, MqttMessage message) throws Exception {
//subscribe后得到的消息会执行到这里面
                    Log.w(TAG, "messageArrived---------- ");
                    Message msg = new Message();
                    msg.what = 1;
                    msg.obj = topic + "---" + message.toString();
                    handler.sendMessage(msg);
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    //publish后会执行到这里
                    Log.w(TAG, "deliveryComplete---------: " + token.isComplete());
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startReconnect() {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new Runnable() {

            @Override
            public void run() {
                if (!client.isConnected()) {
                    connect();
                }
            }
        }, 0 * 1000, 10 * 1000, TimeUnit.MILLISECONDS);
    }

    private void connect() {
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    client.connect(options);
                    Message msg = new Message();
                    msg.what = 2;
                    handler.sendMessage(msg);
                } catch (Exception e) {
                    e.printStackTrace();
                    Message msg = new Message();
                    msg.what = 3;
                    handler.sendMessage(msg);
                }
            }
        }).start();
    }

    //    判断服务是否运行中
    private boolean serviceIsRunning() {
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (SERVICE_CLASSNAME.equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

    public static void stopJooanMQTTService() {
        if (client != null) {
            try {
                client.disconnect();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (scheduler != null) {
            try {
                scheduler.shutdown();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
 
  


import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

/**
 * 发布消息的回调类
 *
 * 必须实现MqttCallback的接口并实现对应的相关接口方法
 *      ◦CallBack 类将实现 MqttCallBack。每个客户机标识都需要一个回调实例。在此示例中,构造函数传递客户机标识以另存为实例数据。
 *      在回调中,将它用来标识已经启动了该回调的哪个实例。
 *  ◦必须在回调类中实现三个方法:
 *
 *http://topmanopensource.iteye.com/blog/1700424
 * @author longgangbai
 */
public class MQTTPushCallback implements MqttCallback {
    private static final String TAG = "PushCallback";

    private ContextWrapper context;

    public JooanMQTTPushCallback(ContextWrapper context) {

        this.context = context;
    }

    /**
     * 接收到消息的回调的方法:接收已经预订的发布
     */
    @Override
    public void messageArrived(String topic, MqttMessage message) throws Exception {
//subscribe(订阅主题)后得到的消息会执行到这里面
//        final NotificationManager notificationManager = (NotificationManager)
//                context.getSystemService(Context.NOTIFICATION_SERVICE);
//
//        final Notification notification = new Notification(R.drawable.snow,
//                "Black Ice Warning!", System.currentTimeMillis());
//
//        // Hide the notification after its selected
//        notification.flags |= Notification.FLAG_AUTO_CANCEL;
//
//        final Intent intent = new Intent(context, BlackIceActivity.class);
//        final PendingIntent activity = PendingIntent.getActivity(context, 0, intent, 0);
//        notification.setLatestEventInfo(context, "Black Ice Warning", "Outdoor temperature is " +
//                new String(message.getPayload()) + "°", activity);
//        notification.number += 1;
//        notificationManager.notify(0, notification);
        Log.w(TAG, "messageArrived: " + "topicName:" + topic + ",messageArrived,订发送消息失败: " + new String(message.getPayload()));
    }

    /**
     *  接收到已经发布的 QoS 1 QoS 2 消息的传递令牌时调用。
     * @param token MqttClient.connect 激活此回调。
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
//We do not need this because we do not publish//publish(发送消息)后会执行到这里
        try {
            Log.i("PushCallback", "deliveryComplete: " + token.getMessage().toString());
        } catch (MqttException e) {
            e.printStackTrace();
        }
        try {
            Log.i(TAG,"Delivery token \"" + token.hashCode());

            System.out.println("订阅主题: " + token.getMessageId());
            System.out.println("消息数据: " + token.getTopics().toString());
            System.out.println("消息级别(0,1,2): " + token.getGrantedQos().toString());
            System.out.println("是否是实时发送的消息(false=实时,true=服务器上保留的最后消息): " + token.isComplete());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 当客户机和broker意外断开时触发
     * 可以再此处理重新订阅
     */
    @Override
    public void connectionLost(Throwable cause) {
        //We should reconnect here  //连接丢失后,一般在这里面进行重连
        Log.w(TAG, "connectionLost: " + cause.getMessage());
        cause.printStackTrace();
    }
}

activity调用发送消息(主题和消息主题与服务器定义一致):

 public String BROKER_URL = "tcp://192.168.1.151:1883";//broker host服务器地址 
private MqttClient mqttClient;
    private String clientId = "qaiot/user/f5c71e03-c324-4b32";
    private String TOPIC = "qaiot/server/user/1.0/cn";


@Override
    protected void onCreate(Bundle savedInstanceState) {//启动服务
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jooan_login);
        startService(new Intent(this,MQTTService.class));
    }
//发送消息代码:
new Thread(new Runnable() {
            @Override
            public void run() {
                LogUtil.i("开始登录");
                try {
                    //创建MqttClient对象
                    mqttClient = new MqttClient(JooanApplication.get().BROKER_URL, clientId, new MemoryPersistence());
                    //MqttClient绑定
                    mqttClient.setCallback(new JooanMQTTPushCallback(JooanLoginActivity.this));


//                    ---------------------------------------------------------------
//                    MqttConnectOptions connOpts = new MqttConnectOptions();
//                    connOpts.setCleanSession(true);
//                    System.out.println("Connecting to broker: "+BROKER_URL);
//                    mqttClient.connect(connOpts);
//                    System.out.println("Connected");
//                    System.out.println("Publishing message: "+"Message from MqttPublishSample");
//                    ---------------------------------------------------------------


                    //MqttClient绑定
                    mqttClient.connect();


                    //Subscribe to all subtopics of homeautomation
//                    mqttClient.subscribe(TOPIC);


                    //创建MQTT相关的主题
                    MqttTopic temperatureTopic = mqttClient.getTopic(TOPIC);
                    Gson gson = new Gson();
                    String toJson = gson.toJson(getData());
                    Log.e("MQTTService", "gson对象:" + toJson);
                    //创建MQTT的消息体
                    MqttMessage message = new MqttMessage(toJson.getBytes());
                    //设置消息传输的类型:消息级别(0,1,2)
                    message.setQos(1);
                    //设置是否在服务器中保存消息体
                    message.setRetained(false);
                    //设置消息的内容
//                    message.setPayload(WSMQTTServerCommon.publication.getBytes());
                    //发送消息并获取回执
                    MqttDeliveryToken token = temperatureTopic.publish(message);//发送消息


//                    token.waitForCompletion();设置超时


                    System.out.println("Publishing \"" + message.toString()
                            + "\" on topic \"" + temperatureTopic.getName() + "\" with QoS = "
                            + message.getQos());
                    System.out.println("For client instance \"" + mqttClient.getClientId()
                            + "\" on address " + mqttClient.getServerURI() + "\"");


                    System.out.println("With delivery token \"" + token.hashCode()
                            + " delivered: " + token.isComplete());


                    //关闭连接
//                    if (mqttClient.isConnected())
//                        mqttClient.disconnect(Integer.parseInt(System.getProperty("timeout", "10000")));
//                    Log.i(TAG, "发送消息的超时时间: "+Integer.parseInt(System.getProperty("timeout", "10000")));
                } catch (MqttException e) {
                    Toast.makeText(getApplicationContext(), "Something went wrong!" + e.getMessage(), Toast.LENGTH_LONG).show();
                    e.printStackTrace();
                    LogUtil.i(e.getMessage());
                }
            }
        }).start();


 @Override
    protected void onDestroy() {
        super.onDestroy();
        recycler_view.clearOnScrollListeners();


        JooanMQTTService.stopMQTTService();//停止服务
        Intent intent = new Intent(this, MQTTService.class);
        stopService(intent);
}

你可能感兴趣的:(Android)