【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

相关文章

Nginx设置连接超时并进行测试的方法步骤

《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

SQL 中多表查询的常见连接方式详解

《SQL中多表查询的常见连接方式详解》本文介绍SQL中多表查询的常见连接方式,包括内连接(INNERJOIN)、左连接(LEFTJOIN)、右连接(RIGHTJOIN)、全外连接(FULLOUTER... 目录一、连接类型图表(ASCII 形式)二、前置代码(创建示例表)三、连接方式代码示例1. 内连接(I

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

java如何通过Kerberos认证方式连接hive

《java如何通过Kerberos认证方式连接hive》该文主要介绍了如何在数据源管理功能中适配不同数据源(如MySQL、PostgreSQL和Hive),特别是如何在SpringBoot3框架下通过... 目录Java实现Kerberos认证主要方法依赖示例续期连接hive遇到的问题分析解决方式扩展思考总

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo

Go语言利用泛型封装常见的Map操作

《Go语言利用泛型封装常见的Map操作》Go语言在1.18版本中引入了泛型,这是Go语言发展的一个重要里程碑,它极大地增强了语言的表达能力和灵活性,本文将通过泛型实现封装常见的Map操作,感... 目录什么是泛型泛型解决了什么问题Go泛型基于泛型的常见Map操作代码合集总结什么是泛型泛型是一种编程范式,允

oracle如何连接登陆SYS账号

《oracle如何连接登陆SYS账号》在Navicat12中连接Oracle11g的SYS用户时,如果设置了新密码但连接失败,可能是因为需要以SYSDBA或SYSOPER角色连接,解决方法是确保在连接... 目录oracle连接登陆NmOtMSYS账号工具问题解决SYS用户总结oracle连接登陆SYS账号

Android kotlin语言实现删除文件的解决方案

《Androidkotlin语言实现删除文件的解决方案》:本文主要介绍Androidkotlin语言实现删除文件的解决方案,在项目开发过程中,尤其是需要跨平台协作的项目,那么删除用户指定的文件的... 目录一、前言二、适用环境三、模板内容1.权限申请2.Activity中的模板一、前言在项目开发过程中,尤