Android Studio connects to Alibaba Cloud to subscribe to topics and then uses JSON to parse the data. It is very easy to use.
Import the MQTT JAR package
There are two methods here:
1. Add dependencies to the project and use Studio to download the library
2. Download the JAR package directly and then import it as a library
Here is the first method:
switch to the Android directory:
just add dependencies as shown below:
implementation("org.eclipse.paho.client.mqttv3-1.2.0")
The second method:
Open Android Studio and switch to the Android directory to find the Lib folder and copy the MQTT JAR package into it.
Then click on the project directory and import the MQTT JAR package into it.
After the addition is completed, import it into the project as a library.
Environment verification:
Enter MQTT anywhere in MainActivity and see if there is a pop-up window.
That’s it and half the battle is over. The next step is to set some permission issues
Give the program network permissions
Switch to the Android directory
and find the following directory:
Add code such as:
<uses-permission android:name="android.permission.INTERNET" />
<!--允许程序获取网络状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
XML layout file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<LinearLayout
android:layout_width="match_parent"
android:background="#51CCDC"
android:orientation="vertical"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:background="#673AB7"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:text="桂航果蔬种植基地"
android:textSize="25sp"
android:textColor="#060A0C"
android:layout_height="match_parent">
</TextView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="20dp">
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
app:cardCornerRadius="20dp">
<ImageView
android:id="@+id/m_img2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg3"
/>
</androidx.cardview.widget.CardView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#51CCDC"
android:orientation="vertical">
<LinearLayout
android:layout_marginBottom="3dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="match_parent"
android:background="@drawable/shape_corner"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="5dp"
android:padding="30dp">
<!--左文字-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="学号:2020070230226"
android:textColor="@color/black"
android:textSize="16sp">
</TextView>
<!--左文字-->
<TextView
android:id="@+id/m_mqtt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text= "姓名:xiao!"
android:textColor="@color/black"
android:textSize="16sp">
</TextView>
</LinearLayout>
</LinearLayout>
<!-- vertical 竖直排列 -->
<!-- horizontal 竖直排列 -->
<!-- 数据解析界面 -->
<LinearLayout
android:layout_marginTop="10dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFF">
<!-- 包裹其他界面-->
<LinearLayout
android:layout_margin="5px"
android:padding="3dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:gravity="center"
android:layout_weight="1"
android:orientation="horizontal"
android:layout_height="match_parent">
<!--气温-->
<LinearLayout
android:layout_width="160dp"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/shape_corner"
android:layout_height="105dp">
<ImageView
android:id="@+id/test"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:src="@drawable/air_temp"
android:layout_marginRight="15dp">
</ImageView>
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="温度"
android:textSize="25sp">
</TextView>
<!-- 数值 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/air_temp"
android:layout_width="wrap_content"
android:text=" 0 "
android:textSize="25sp"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!--The End -->
<!-- 湿度-->
<LinearLayout
android:layout_marginLeft="25dp"
android:layout_width="160dp"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/shape_corner"
android:layout_height="105dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:src="@drawable/air_humi"
android:layout_marginRight="15dp">
</ImageView>
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="湿度"
android:textSize="20sp">
</TextView>
<!-- 数值 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/air_humi"
android:layout_width="wrap_content"
android:text=" 0 "
android:textSize="25sp"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!--The End -->
</LinearLayout>
<!-- 2 -->
<LinearLayout
android:layout_width="match_parent"
android:background="#FFFF"
android:layout_margin="5px"
android:padding="3dp"
android:layout_height="wrap_content">
<!-- Layout1-->
<LinearLayout
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="match_parent">
<!--气温-->
<!--Left1 -->
<LinearLayout
android:layout_width="160dp"
android:layout_weight="1"
android:gravity="center"
android:background="@drawable/shape_corner"
android:layout_height="105dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:src="@drawable/soil_humi"
android:layout_marginRight="15dp">
</ImageView>
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="土壤湿度"
android:textSize="20sp">
</TextView>
<!-- 数值 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/sloi_humi"
android:layout_width="wrap_content"
android:text=" 0 "
android:textSize="25sp"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!--The End -->
<!-- 湿度-->
<LinearLayout
android:layout_width="160dp"
android:layout_weight="1"
android:gravity="center"
android:layout_marginLeft="25dp"
android:background="@drawable/shape_corner"
android:layout_height="105dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:src="@drawable/n2"
android:layout_marginRight="15dp">
</ImageView>
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="土壤含氮"
android:textSize="20sp">
</TextView>
<!-- 数值 -->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/soli_n"
android:layout_width="wrap_content"
android:text=" 0 "
android:textSize="25sp"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<!-- The End -->
<!-- 3 -->
<LinearLayout
android:layout_margin="5px"
android:padding="3dp"
android:layout_width="match_parent"
android:orientation="horizontal"
android:gravity="center"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="160dp"
android:background="@drawable/shape_corner"
android:layout_weight="1"
android:gravity="center"
android:layout_height="105dp">
<ImageView
android:layout_weight="1"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:src="@drawable/p2"
android:layout_marginRight="15dp">
</ImageView>
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_width="wrap_content"
android:text="土壤含磷"
android:textSize="20sp"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/soil_p"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:text=" 0 "
android:textSize="25sp"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
</LinearLayout>
<!--L1-->
<LinearLayout
android:layout_marginLeft="25dp"
android:gravity="center"
android:layout_weight="1"
android:layout_width="160dp"
android:orientation="horizontal"
android:background="@drawable/shape_corner"
android:layout_height="105dp">
<ImageView
android:layout_weight="1"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginTop="10dp"
android:src="@drawable/k2"
android:layout_marginRight="15dp">
</ImageView>
<LinearLayout
android:layout_width="wrap_content"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_marginRight="5dp"
android:layout_width="wrap_content"
android:text="土壤含钾"
android:textSize="20sp"
android:layout_height="wrap_content">
</TextView>
<TextView
android:id="@+id/soil_k"
android:layout_width="wrap_content"
android:text=" 0 "
android:textSize="25sp"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
</LinearLayout>
<!--Layout2-->
</LinearLayout>
<!-- The End -->
</LinearLayout>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
The effect is as follows:
The main code of MainActivitive.java is as follows:
package com.example.ks_wfs;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.net.wifi.aware.DiscoverySession;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.concurrent.ScheduledExecutorService;
public class MainActivity extends AppCompatActivity {
private Handler handler;
private String serverUri = "自己的IP地址";
/* private String serverUri = "tcp://iot.qaeb.cn:1883";*/
/*
这里可以填上各种云平台的物联网云平的域名+1883端口号,什么阿里云腾讯云百度云天工物接入都可以,
这里我填的是我在我的阿里云服务器上搭建的EMQ平台的地址,
注意:前缀“tcp://”不可少,之前我没写,怎么都连不上,折腾了好久
*/
private String userName = " ";
private String passWord = " ";
private String clientId = "app"+System.currentTimeMillis(); //clientId很重要,不能重复,否则就会连不上,所以我定义成 app+当前时间
private String mqtt_sub_topic = "/iotsoil/post"; //需要订阅的主题
private String mqtt_pub_topic = "xiao"; //需要发布的主题
private MqttClient mqtt_client; //创建一个mqtt_client对象
MqttConnectOptions options;
private TextView air_temp;
private TextView air_humi;
private TextView sloi_humi;
private TextView soli_n;
private TextView soil_p;
private TextView soil_k;
private ImageView test;
private ScheduledExecutorService scheduler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* xiaobai
* 2023.10.10
* Version V1.0
*/
/*绑定UI文件*/
UI_Init();/*类似单片机的初始化*/
mqtt_init_Connect();/*初始化连接函数*/
/*回调函数,数据会在回调函数里面*/
mqtt_client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable throwable) {
}
@Override
public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
/*数据到这了*/
final String msg = new String(mqttMessage.getPayload());
Log.d("MQTTRCV", msg);//日志信息,可以查看
System.out.println(msg);/*打印得到的数据*/
/*更新UI线程*/
/* runOnUiThread(new Runnable() {
@Override
public void run() {
*//*开始解析数据*//*
*//*数据解析部分这里使用的是Json解析*//*
*//*为了避免闪退,使用try来处理异常情况*//*
try {
JSONObject jsonObject = new JSONObject(String.valueOf(msg));
String method = jsonObject.getString("method");
JSONObject params = jsonObject.getJSONObject("params");
int soilHumidity = params.getInt("soilHumidity");
int currentTemperature = params.getInt("CurrentTemperature");
int currentHumidity = params.getInt("CurrentHumidity");
int n = params.getInt("N");
int p = params.getInt("P");
int k = params.getInt("K");
*//*更新数据到UI*//*
air_temp.setText(String.valueOf(currentTemperature));
air_humi.setText(String.valueOf(currentHumidity));
sloi_humi.setText(String.valueOf(soilHumidity));
soli_n.setText(String.valueOf(n));
soil_p.setText(String.valueOf(p));
soil_k.setText(String.valueOf(k));
*//*打印日志信息*//*
Log.d("TAG", "method: " + method);
Log.d("TAG", "soilHumidity: " + soilHumidity);
Log.d("TAG", "currentTemperature: " + currentTemperature);
Log.d("TAG", "currentHumidity: " + currentHumidity);
Log.d("TAG", "N: " + n);
Log.d("TAG", "P: " + p);
Log.d("TAG", "K: " + k);
}catch (JSONException e)
{
e.printStackTrace();
Toast.makeText(MainActivity.this ,"数据解析异常!",Toast.LENGTH_LONG).show();
}
}
});*/
/*下面是带弹窗显示的代码数据已经解析完成,解开注释即可*/
runOnUiThread(new Runnable() {
@Override
public void run() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("MQTT消息");
builder.setMessage(msg);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
// 点击确定按钮后的操作
/* 开始解析数据*/
/* 数据解析部分这里使用的是Json解析
为了避免闪退,使用try来处理异常情况*/
try {
JSONObject jsonObject = new JSONObject(String.valueOf(msg));
String method = jsonObject.getString("method");
JSONObject params = jsonObject.getJSONObject("params");
int soilHumidity = params.getInt("soilHumidity");
int currentTemperature = params.getInt("CurrentTemperature");
int currentHumidity = params.getInt("CurrentHumidity");
int n = params.getInt("N");
int p = params.getInt("P");
int k = params.getInt("K");
/* 更新UI*/
air_temp.setText(String.valueOf(currentTemperature));
air_humi.setText(String.valueOf(currentHumidity));
sloi_humi.setText(String.valueOf(soilHumidity));
soli_n.setText(String.valueOf(n));
soil_p.setText(String.valueOf(p));
soil_k.setText(String.valueOf(k));
/* 打印输出的信息*/
Log.d("TAG", "method: " + method);
Log.d("TAG", "soilHumidity: " + soilHumidity);
Log.d("TAG", "currentTemperature: " + currentTemperature);
Log.d("TAG", "currentHumidity: " + currentHumidity);
Log.d("TAG", "N: " + n);
Log.d("TAG", "P: " + p);
Log.d("TAG", "K: " + k);
}catch (JSONException e)
{
e.printStackTrace();
Toast.makeText(MainActivity.this ,"数据解析异常!",Toast.LENGTH_LONG).show();
}
}
});
builder.show();
}
});
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
});
/*点击事件*/
test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PublishMessage(mqtt_pub_topic,"{\"params\":{\"我是小白,你好呀\":999 } }");
}
});
}
public void mqtt_init_Connect()
{
try {
//实例化mqtt_client,填入我们定义的serverUri和clientId,然后MemoryPersistence设置clientid的保存形式,默认为以内存保存
mqtt_client = new MqttClient(serverUri,clientId,new MemoryPersistence());
//创建并实例化一个MQTT的连接参数对象
options = new MqttConnectOptions();
//然后设置对应的参数
options.setUserName(userName); //设置连接的用户名
options.setPassword(passWord.toCharArray()); //设置连接的密码
options.setConnectionTimeout(30); // 设置超时时间,单位为秒
options.setKeepAliveInterval(50); //设置心跳,30s
options.setAutomaticReconnect(true); //是否重连
//设置是否清空session,设置为false表示服务器会保留客户端的连接记录,设置为true表示每次连接到服务器都以新的身份连接
options.setCleanSession(false);
/*初始化成功之后就开始连接*/
connect();
Toast.makeText(MainActivity.this,"连接成功",Toast.LENGTH_LONG).show();
}catch (Exception e) {
e.printStackTrace();
Toast.makeText(MainActivity.this,"失败",Toast.LENGTH_LONG).show();
}
}
public void connect(){
//连接mqtt服务器
try {
mqtt_client.connect(options);
mqtt_client.subscribe(mqtt_sub_topic);
Toast.makeText(this ,"开始建立连接.....!",Toast.LENGTH_LONG).show();
}catch (Exception e) {
e.printStackTrace();
Log.d("MQTTCon","mqtt连接失败");
Toast.makeText(this ,"mqtt连接失败!",Toast.LENGTH_LONG).show();
}
}
/*绑定各个UI控件*/
public void UI_Init()
{
air_temp = findViewById(R.id.air_temp); //空气温度
air_humi = findViewById(R.id.air_humi);//空气湿度
sloi_humi = findViewById(R.id.sloi_humi);//土壤湿度
soli_n = findViewById(R.id.soli_n);//土壤含N量
soil_p = findViewById(R.id.soil_p);//土壤含P量
soil_k = findViewById(R.id.soil_k);//土壤含K量
test = findViewById(R.id.test);//测试按钮
}
/*发布函数!*/
private void PublishMessage(String topic,String Message2)
{
if(mqtt_client ==null || !mqtt_client.isConnected())
{
return;
}
MqttMessage message = new MqttMessage();
message.setPayload(Message2.getBytes());
try{
mqtt_client.publish(topic,message);
}catch (MqttException e)
{
e.printStackTrace();
}
}
}