前言:
亲测可行,本文实现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() { @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<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-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<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 android:layout tools:context=".MainActivity"> <TextView android:id="@+id/msgTextView" android:layout android:layout android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:padding="10dp" android:text="就你也会点灯?" android:textColor="#E91E63" android:textSize="36sp" android:text app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.536" app:layout_constraintStart_toStartOf="parent" tools:layout_editor_absoluteY="128dp" /> <Button android:id="@+id/activate_button" android:layout android:layout 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" /> <Button android:id="@+id/post_button1" android:layout android:layout 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" /> <Button android:id="@+id/post_button2" android:layout android:layout android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:layout_marginTop="6dp" android:layout_marginEnd="10dp" android:text="灭灯" />
参考链接:跟我做,让Android封装MQTT连接阿里云平台!【开源】_跟我做,让安卓封装mqtt-CSDN博客
本文参考的APP源码:GitCode - 开发者的代码家园
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)