zoukankan      html  css  js  c++  java
  • 安卓开发之mqtt协议

    首先物联网协议mqtt协议是基于tcp/ip协议的,使用了官方的mqttclient框架

    /*
    *初始化mqttclient
    */
    private void init() {
    try {
    //MQTT的连接设置
    options = new MqttConnectOptions();
    //host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
    client = new MqttClient(new Ip().host, username,
    new MemoryPersistence());
    //设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
    options.setCleanSession(false);
    //options.setWill(myTopic,null,2,false);

    //设置连接的用户名
    options.setUserName(login_token);
    //设置连接的密码
    options.setPassword(passWord.toCharArray());
    // 设置超时时间 单位为秒
    options.setConnectionTimeout(10);
    // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
    options.setKeepAliveInterval(60);
    //设置回调
    client.setCallback(new MqttCallback() {
    @Override
    public void connectionLost(Throwable cause) {
    //连接丢失后,一般在这里面进行重连
    System.out.println("connectionLost----------");

    }

    @Override
    public void deliveryComplete(IMqttDeliveryToken token) {
    //publish后会执行到这里
    System.out.println("deliveryComplete---------"
    + token.isComplete());
    }
    @Override
    public void messageArrived(String topicName, MqttMessage message)
    throws Exception {
    byte[] message1 = message.getPayload();
    // subscribe后得到的消息会执行到这里面
    System.out.println("messageArrived----------" + message1[0] + Arrays.toString(message1));
    System.out.println(message1[0] == 5);
    String id = new String(subBytes(message1, 1, 16), "UTF-8");

    System.out.print("mqtt收到的id" + id);
    DeviceList device = getBookById(id);
    System.out.print("device" + device.getName());
    String name = device.getName();
    String gName = device.getgName();
    String type = device.getType();
    System.out.print("名字为" + name + gName);
    /**
    * 使用handler发送matt接收的消息,格式为二进制数据
    * */

    Message msg = new Message();
    msg.what = 1;
    if (message1[0] == 1) {
    // msg.obj = name + "设备心跳";
    // handler.sendMessage(msg);
    return;
    }
    if (message1[0] == 2) {
    msg.obj = gName + "" + name + "报警";
    msg.arg1 = Integer.parseInt(type);
    handler.sendMessage(msg);
    return;
    }
    if (message1[0] == 3) {
    msg.obj = gName + "" + name + "上线";
    handler.sendMessage(msg);
    return;
    }
    if (message1[0] == 4) {
    msg.obj = gName + "" + name + "离线";
    handler.sendMessage(msg);
    return;
    }
    if (message1[0] == 5) {
    if (message1[17] == 0) {
    msg.obj = gName + "" + name + "关门";
    } else {
    msg.obj = gName + "" + name + "开门";
    }


    handler.sendMessage(msg);
    return;
    }
    if (message1[0] == 20 && message1[17] > 0 && message1[17] < 20) {

    msg.obj = name + "电池电量: " + message1[17] + "%";
    handler.sendMessage(msg);
    System.out.println("电池:" + name + "电池电量: " + message1[17] + "%");
    return;
    }
    if (message1[17] > 0) {
    SharedPreferences sp = getActivity().getSharedPreferences(id, getActivity().MODE_PRIVATE);
    // 获得sp的编辑器
    SharedPreferences.Editor ed = sp.edit();
    // 以键值对的显示将用户名和密码保存到sp中
    ed.putString("battery", String.valueOf(message1[17]));
    // 提交用户名和密码
    ed.commit();
    }
    }
    });
    } catch (Exception e) {
    e.printStackTrace();
    }
    }

    public byte[] subBytes(byte[] src, int begin, int count) {
    byte[] bs = new byte[count];
    System.arraycopy(src, begin, bs, 0, count);
    return bs;
    }

    //根据id拿到属性为id的Book对象。
    public static DeviceList getBookById(String id) {
    DeviceList book = new DeviceList();
    book.setId(id);//设置传入的id值
    //books.indexOf()根据id比较对象是否相等
    return deviceList1.get(deviceList1.indexOf(book));
    //返回关联id的Book对象。
    }

    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();
    }

    protected boolean onKeyDown(int keyCode, KeyEvent event) {
    if (client != null && keyCode == KeyEvent.KEYCODE_BACK) {
    try {
    client.disconnect();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    return super.getActivity().onKeyDown(keyCode, event);
    }

    @Override
    public void onDestroy() {
    super.onDestroy();
    try {
    scheduler.shutdown();
    client.disconnect();
    } catch (MqttException 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);
    }
    其次使用handlermessage接收消息,并已notifacation的形式展示在通知栏页面
     handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
    super.handleMessage(msg);
    if (msg.what == 1) {
    NotificationManager manager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);
    Notification myNotify = new Notification();
    myNotify.icon = R.drawable.logo;
    myNotify.tickerText = "新消息";
    myNotify.when = System.currentTimeMillis();
    //使用默认的声音
    myNotify.defaults |= Notification.DEFAULT_SOUND;

    //使用默认的震动
    myNotify.defaults |= Notification.DEFAULT_VIBRATE;

    //使用默认的声音、振动、闪光
    myNotify.defaults = Notification.DEFAULT_ALL;
    // myNotify.flags=Notification.FLAG_AUTO_CANCEL;
    // myNotify.flags = Notification.FLAG_NO_CLEAR;// 不能够自动清除
    RemoteViews rv = new RemoteViews(getActivity().getPackageName(),
    R.layout.activity_notification1);
    rv.setTextViewText(R.id.tv_desc, (String) msg.obj);
    myNotify.contentView = rv;
    Intent intent = new Intent(getActivity(), MainActivity.class);
    // intent.addCategory(Intent.CATEGORY_LAUNCHER);
    // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    android.app.PendingIntent contentIntent = android.app.PendingIntent.getActivity(getActivity(), 0,
    intent, 0);
    myNotify.contentIntent = contentIntent;
    manager.notify(i1++, myNotify);
    PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
    PowerManager.WakeLock wakeLock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |
    PowerManager.SCREEN_DIM_WAKE_LOCK, "target");
    boolean screen = pm.isScreenOn();
    if (!screen) {//如果灭屏
    wakeLock.acquire();
    wakeLock.release();
    }
    refresh();
    } else if (msg.what == 2) {
    System.out.println("连接成功");
    System.out.print("连接成功大小" + listDatas2.size());
    try {
    client.subscribe(myTopic, 1);
    client.subscribe(myTopic1, 1);
    } catch (MqttException e) {
    e.printStackTrace();
    }
    } else if (msg.what == 3) {
    //Toast.makeText(MainActivity.this, "连接失败,系统正在重连", Toast.LENGTH_SHORT).show();
    System.out.println("连接失败,系统正在重连");
    }
    }
    };
  • 相关阅读:
    git上刚下载的项目就显示有改动
    Windows Server 2012 R2安装Oracle 11g问题
    maven项目更换本地仓库
    dom4j创建和解析xml文档
    java倒计时三种简单实现方式
    JS倒计时两种种实现方式
    java加载properties文件的六中基本方式实现
    MYSQL 高级语法
    MYSQL 基础语法
    Sql 代码规范说明
  • 原文地址:https://www.cnblogs.com/wuxilvxin/p/8042481.html
Copyright © 2011-2022 走看看