前言:

亲测可行,本文实现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 添加网络权限

 位置如下所示:

​ 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() {

@Override

public 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生命周期函数

@Override

protected 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 params = new HashMap(16);

params.put("productKey", productKey);

params.put("deviceName", deviceName);

params.put("clientId", clientId);

String timestamp = String.valueOf(System.currentTimeMillis());

params.put("timestamp", timestamp);

// cn-shanghai

String 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.1

connOpts.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 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设计

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">

android: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" />

android: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" />

android: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" />

android: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 - 开发者的代码家园

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: