【Android+物联网】Android封装MQTT连接阿里云物联网平台

2024-01-12 23:12

本文主要是介绍【Android+物联网】Android封装MQTT连接阿里云物联网平台,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

亲测可行,本文实现Android封装MQTT连接阿里云物联网平台。将MQTT协议和连接阿里云平台的操作通过Android studio写入APP中,并简单设计UI。实现手机APP远程控制单片机LED灯亮灭的功能。

关于《Android软件开发》,见如下专栏

https://blog.csdn.net/m0_61712829/category_12455686.html?spm=1001.2014.3001.5482

 关于《完整实现STM32+ESP8266+MQTT+阿里云+APP》,见如下专栏

https://blog.csdn.net/m0_61712829/category_12545281.html?spm=1001.2014.3001.5482

源码可于上方资源绑定栏下载。

1.下载mqtt.jar包

下载链接:Index of /repositories/paho-releases/org/eclipse/paho

选取org.eclipse.paho.client.mqttv3/1.2.2/org.eclipse.paho.client.mqttv3-1.2.2.jar下载

进入链接后,过程如下:

首先,选取 org.eclipse.paho.client.mqttv3/ 
 

​选择 1.2.1/

选取 org.eclipse.paho.client.mqttv3-1.2.2.jar 进行下载

下载成功如下

然后,将下载成功的jar包拷贝到你工程的app/libs目录

2.导入mqtt.jar包

点击项目页面最右边的设置按钮,选择 Project Structure..

进入后,按如下图顺序点击选择 

在step1. 处输入路径 libs\org.eclipse.paho.client.mqttv3-1.2.2.jar

导入mqtt.jar包成功,点击ok

​ 3.程序说明

1.在 AndroidManifest.xml 添加网络权限

</application><uses-permission android:name="android.permission.INTERNET" />
</manifest>

 位置如下所示:

​ 2.在 MainActivity.java 添加包

MainActivity.java 在如下位置

注意:将代码中涉及的工程名改为你的工程名 

package com.example.test;import androidx.appcompat.app.AppCompatActivity;import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;import com.example.test.AliyunIoTSignUtil;import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

 3.在MainActivity.java中的public class MainActivity extends AppCompatActivity {}中初始定义一些基本信息

注意:将productKey、deviceName、deviceSecret 改为你自己的;将json数据格式中的标识符改为你自己的

 private static final String TAG =MainActivity.class.getSimpleName();private TextView msgTextView;private String productKey="a16OKk6dTya";private String deviceName="KAMI";private String deviceSecret="8790bd0545dd874d77fcac85729fc4bf";private final String payloadJson1="{\"ParkingState\":1}";private final String payloadJson2="{\"ParkingState\":0}";private MqttClient mqttClient=null;final int POST_DEVICE_PROPERTIES_SUCCESS = 1002;final int POST_DEVICE_PROPERTIES_ERROR = 1003;private String responseBody = "";private Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case POST_DEVICE_PROPERTIES_SUCCESS:showToast("发送数据成功");break;case POST_DEVICE_PROPERTIES_ERROR:showToast("post数据失败");break;}}};

 4.在MainActivity.java中,写开始APP生命周期函数

  @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);msgTextView = findViewById(R.id.msgTextView);findViewById(R.id.activate_button).setOnClickListener((l) -> {new Thread(() -> initAliyunIoTClient()).start();});findViewById(R.id.post_button1).setOnClickListener((l) -> {mHandler.postDelayed(() -> postDeviceProperties1(), 1000);});findViewById(R.id.post_button2).setOnClickListener((l) -> {mHandler.postDelayed(() -> postDeviceProperties2(), 1000);});}

5.在MainActivity.java中,写连接阿里云物联网平台函数

 private void initAliyunIoTClient() {try {String clientId = "12345"+ System.currentTimeMillis();Map<String, String> params = new HashMap<String, String>(16);params.put("productKey", productKey);params.put("deviceName", deviceName);params.put("clientId", clientId);String timestamp = String.valueOf(System.currentTimeMillis());params.put("timestamp", timestamp);// cn-shanghaiString targetServer ="tcp://"+ productKey + ".iot-as-mqtt.cn-shanghai.aliyuncs.com:1883";String mqttclientId = clientId + "|securemode=3,signmethod=hmacsha1,timestamp=" + timestamp + "|";String mqttUsername = deviceName + "&" + productKey;String mqttPassword = AliyunIoTSignUtil.sign(params, deviceSecret, "hmacsha1");connectMqtt(targetServer, mqttclientId, mqttUsername, mqttPassword);} catch (Exception e) {e.printStackTrace();responseBody = e.getMessage();mHandler.sendEmptyMessage(POST_DEVICE_PROPERTIES_ERROR);}}

6.在MainActivity.java中,写登陆MQTT函数

 public void connectMqtt(String url, String clientId, String mqttUsername, String mqttPassword) throws Exception {MemoryPersistence persistence = new MemoryPersistence();mqttClient = new MqttClient(url, clientId, persistence);MqttConnectOptions connOpts = new MqttConnectOptions();// MQTT 3.1.1connOpts.setMqttVersion(4);connOpts.setAutomaticReconnect(true);connOpts.setCleanSession(true);connOpts.setUserName(mqttUsername);connOpts.setPassword(mqttPassword.toCharArray());connOpts.setKeepAliveInterval(60);mqttClient.connect(connOpts);Log.d(TAG, "connected " + url);}

7.在MainActivity.java中,写发布主题Publish函数

    private void postDeviceProperties1() {try {Random random = new Random();//上报数据String payload = String.format(payloadJson1, String.valueOf(System.currentTimeMillis()), 10 + random.nextInt(20), 50 + random.nextInt(50));responseBody = payload;MqttMessage message = new MqttMessage(payload.getBytes("utf-8"));message.setQos(1);String pubTopic = "/" + productKey + "/" + deviceName + "/user/update";mqttClient.publish(pubTopic, message);Log.d(TAG, "publish topic=" + pubTopic + ",payload=" + payload);mHandler.sendEmptyMessage(POST_DEVICE_PROPERTIES_SUCCESS);mHandler.postDelayed(() -> postDeviceProperties1(), 5 * 1000);} catch (Exception e) {e.printStackTrace();responseBody = e.getMessage();mHandler.sendEmptyMessage(POST_DEVICE_PROPERTIES_ERROR);Log.e(TAG, "postDeviceProperties error " + e.getMessage(), e);}}private void postDeviceProperties2() {try {Random random = new Random();//上报数据String payload = String.format(payloadJson2, String.valueOf(System.currentTimeMillis()), 10 + random.nextInt(20), 50 + random.nextInt(50));responseBody = payload;MqttMessage message = new MqttMessage(payload.getBytes("utf-8"));message.setQos(1);String pubTopic = "/" + productKey + "/" + deviceName + "/user/update";mqttClient.publish(pubTopic, message);Log.d(TAG, "publish topic=" + pubTopic + ",payload=" + payload);mHandler.sendEmptyMessage(POST_DEVICE_PROPERTIES_SUCCESS);mHandler.postDelayed(() -> postDeviceProperties2(), 5 * 1000);} catch (Exception e) {e.printStackTrace();responseBody = e.getMessage();mHandler.sendEmptyMessage(POST_DEVICE_PROPERTIES_ERROR);Log.e(TAG, "postDeviceProperties error " + e.getMessage(), e);}}private void showToast(String msg) {msgTextView.setText(msg + "\n" + responseBody);}}

8.解码获取password,在《物联网却不能物物相联?阿里云物联网平台得这么设置!》里面如果得到了password,不用这个class也行

在如下位置添加 AliyunIoTSignUtil.java

 AliyunIoTSignUtil.java中的代码如下

package com.example.test;import java.util.Arrays;
import java.util.Map;import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;public class AliyunIoTSignUtil {public static String sign(Map<String, String> params, String deviceSecret, String signMethod) {//将参数Key按字典顺序排序String[] sortedKeys = params.keySet().toArray(new String[] {});Arrays.sort(sortedKeys);//生成规范化请求字符串StringBuilder canonicalizedQueryString = new StringBuilder();for (String key : sortedKeys) {if ("sign".equalsIgnoreCase(key)) {continue;}canonicalizedQueryString.append(key).append(params.get(key));}try {String key = deviceSecret;return encryptHMAC(signMethod,canonicalizedQueryString.toString(), key);} catch (Exception e) {throw new RuntimeException(e);}}/*** HMACSHA1加密**/public static String encryptHMAC(String signMethod, String content, String key) throws Exception {SecretKey secretKey = new SecretKeySpec(key.getBytes("utf-8"), signMethod);Mac mac = Mac.getInstance(secretKey.getAlgorithm());mac.init(secretKey);byte[] data = mac.doFinal(content.getBytes("utf-8"));return bytesToHexString(data);}public static final String bytesToHexString(byte[] bArray) {StringBuffer sb = new StringBuffer(bArray.length);String sTemp;for (int i = 0; i < bArray.length; i++) {sTemp = Integer.toHexString(0xFF & bArray[i]);if (sTemp.length() < 2) {sb.append(0);}sb.append(sTemp.toUpperCase());}return sb.toString();}}

9. 简单UI设计

<?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"><TextViewandroid:id="@+id/msgTextView"android:layout_width="62dp"android:layout_height="563dp"android:layout_alignParentStart="true"android:layout_alignParentTop="true"android:padding="10dp"android:text="就你也会点灯?"android:textColor="#E91E63"android:textSize="36sp"android:textStyle="bold"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.536"app:layout_constraintStart_toStartOf="parent"tools:layout_editor_absoluteY="128dp" /><Buttonandroid:id="@+id/activate_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:layout_alignParentEnd="true"android:layout_alignParentRight="true"android:layout_marginTop="7dp"android:layout_marginEnd="232dp"android:layout_marginRight="232dp"android:padding="10dp"android:text="激活"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"tools:layout_editor_absoluteY="274dp" /><Buttonandroid:id="@+id/post_button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentStart="true"android:layout_alignParentLeft="true"android:layout_alignParentTop="true"android:layout_marginStart="205dp"android:layout_marginLeft="205dp"android:layout_marginTop="6dp"android:layout_marginBottom="10dp"android:padding="10dp"android:text="点灯"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.498"app:layout_constraintStart_toStartOf="parent"tools:layout_editor_absoluteY="351dp" /><Buttonandroid:id="@+id/post_button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentTop="true"android:layout_alignParentEnd="true"android:layout_marginTop="6dp"android:layout_marginEnd="10dp"android:text="灭灯" />

参考链接:跟我做,让Android封装MQTT连接阿里云平台!【开源】_跟我做,让安卓封装mqtt-CSDN博客

 本文参考的APP源码:GitCode - 开发者的代码家园

这篇关于【Android+物联网】Android封装MQTT连接阿里云物联网平台的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/599466

相关文章

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Spring Boot 整合 MyBatis 连接数据库及常见问题

《SpringBoot整合MyBatis连接数据库及常见问题》MyBatis是一个优秀的持久层框架,支持定制化SQL、存储过程以及高级映射,下面详细介绍如何在SpringBoot项目中整合My... 目录一、基本配置1. 添加依赖2. 配置数据库连接二、项目结构三、核心组件实现(示例)1. 实体类2. Ma

电脑win32spl.dll文件丢失咋办? win32spl.dll丢失无法连接打印机修复技巧

《电脑win32spl.dll文件丢失咋办?win32spl.dll丢失无法连接打印机修复技巧》电脑突然提示win32spl.dll文件丢失,打印机死活连不上,今天就来给大家详细讲解一下这个问题的解... 不知道大家在使用电脑的时候是否遇到过关于win32spl.dll文件丢失的问题,win32spl.dl

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

Windows Server服务器上配置FileZilla后,FTP连接不上?

《WindowsServer服务器上配置FileZilla后,FTP连接不上?》WindowsServer服务器上配置FileZilla后,FTP连接错误和操作超时的问题,应该如何解决?首先,通过... 目录在Windohttp://www.chinasem.cnws防火墙开启的情况下,遇到的错误如下:无法与

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)

《Java导入、导出excel用法步骤保姆级教程(附封装好的工具类)》:本文主要介绍Java导入、导出excel的相关资料,讲解了使用Java和ApachePOI库将数据导出为Excel文件,包括... 目录前言一、引入Apache POI依赖二、用法&步骤2.1 创建Excel的元素2.3 样式和字体2.

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

IDEA连接达梦数据库的详细配置指南

《IDEA连接达梦数据库的详细配置指南》达梦数据库(DMDatabase)作为国产关系型数据库的代表,广泛应用于企业级系统开发,本文将详细介绍如何在IntelliJIDEA中配置并连接达梦数据库,助力... 目录准备工作1. 下载达梦JDBC驱动配置步骤1. 将驱动添加到IDEA2. 创建数据库连接连接参数