1、第一步
需要准备一下:添加依赖、创建一个aseets的目录、引入echarts.min.js和jquery.js文件、创建一个html文件
implementation 'com.github.abel533:ECharts:3.0.0.2'
implementation 'com.google.code.gson:gson:2.8.1'
2、第二步
贴上html文件,这里是一个双折线图
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
#main{
width: 360px;
height: 400px;
}
</style>
</head>
<body>
<script type="text/javascript" src="./echarts.min.js"></script>
<script type="text/javascript" src="./jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="./jquery.js"></script>
<div id="main"></div>
<script type="text/javascript">
$(window).load(function(){
$(".loading").fadeOut()
})
$(function() {
updateChartWithData();
});
function updateChartWithData(oneCOArray,methaneArray) {
var myChart = echarts.init(document.getElementById('main'));
var option;
option = {
title: {
text: ''
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
legend: {
data: ['一氧化碳', '甲烷']
},
toolbox: {
feature: {
saveAsImage: {}
}
},
grid: {
left: '1%',
right: '12%',
bottom: '29%',
containLabel: true
},
xAxis: [
{
name: '(min)',
type: 'category',
nameLocation: 'middle',
nameGap: 25,
boundaryGap: false,
data: ['1', '2', '3', '4', '5', '7', '8', '9', '10']
}
],
yAxis: [
{
name: '(ppm/%)',
nameGap: 30,
type: 'value'
}
],
series: [
{
name: '一氧化碳',
type: 'line',
stack: 'Total',
areaStyle: {},
emphasis: {
focus: 'series'
},
data:oneCOArray
},
{
name: '甲烷',
type: 'line',
stack: 'Total',
label: {
show: true,
position: 'top'
},
areaStyle: {},
emphasis: {
focus: 'series'
},
data:methaneArray
}
]
};
option && myChart.setOption(option);
}
</script>
</body>
</html>
3、第三步
准备好一个布局文件,界面如下图所示
<?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:orientation="vertical"
android:id="@+id/device_pageTwo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="55dp">
<!--标题-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设备监测"
android:textColor="@color/black"
android:textSize="25sp"
android:textStyle="bold"
android:layout_centerInParent="true"/>
</RelativeLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--状态面板-->
<!--面板2-->
<androidx.cardview.widget.CardView
android:id="@+id/cardView_state_two"
android:layout_width="match_parent"
android:layout_height="175dp"
android:layout_marginBottom="1dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:cardCornerRadius="20dp">
<!--橙色的标识 -->
<View
android:layout_width="5dp"
android:layout_height="16dp"
android:background="#19D3E0"
android:layout_marginLeft="15dp"
android:layout_marginTop="12dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginTop="6dp"
android:text="状态:"
android:textSize="19dp"
android:textColor="@color/black"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="37dp"
android:layout_marginRight="15dp"
android:background="#C5C0C0"/>
<!--运行状态-->
<TextView
android:id="@+id/standby_text_two"
android:layout_width="110dp"
android:layout_height="30dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="55dp"
android:text="运行状态:"
android:textSize="18dp"
android:textStyle="bold"/>
<!--运行状态的文本值-->
<TextView
android:id="@+id/yunXi"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="130dp"
android:layout_marginTop="53dp"
android:text="暂无状态"
android:textSize="23dp"
android:textColor="#FFA500"
android:textStyle="bold"/>
<!--圆点-->
<ImageView
android:id="@+id/yunXi_point"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginLeft="242dp"
android:layout_marginTop="63dp"
android:src="@drawable/circle_red"/>
<!--工作模式-->
<TextView
android:id="@+id/fault_text_two"
android:layout_width="110dp"
android:layout_height="30dp"
android:layout_marginLeft="20dp"
android:layout_marginTop="105dp"
android:text="工作模式:"
android:textSize="18dp"
android:textStyle="bold"/>
<!--运行状态的文本值-->
<TextView
android:id="@+id/gongZuo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="130dp"
android:layout_marginTop="103dp"
android:text="暂无状态"
android:textSize="23dp"
android:textColor="#FFA500"
android:textStyle="bold"/>
<ImageView
android:id="@+id/gongZuo_point"
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_marginLeft="242dp"
android:layout_marginTop="110dp"
android:src="@drawable/circle_green"/>
</androidx.cardview.widget.CardView>
<!--面板2-->
<!--面板3-->
<androidx.cardview.widget.CardView
android:id="@+id/cardView_now_two"
android:layout_width="match_parent"
android:layout_height="350dp"
android:layout_marginBottom="1dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:cardCornerRadius="20dp">
<WebView
android:id="@+id/echarts_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardView_complete_two"
android:layout_width="match_parent"
android:layout_height="170dp"
android:layout_marginBottom="1dp"
app:cardElevation="5dp"
app:cardUseCompatPadding="true"
app:cardCornerRadius="20dp">
<!--橙色的标识3-->
<View
android:layout_width="5dp"
android:layout_height="16dp"
android:background="#19D3E0"
android:layout_marginLeft="15dp"
android:layout_marginTop="12dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginTop="6dp"
android:text="系统数据:"
android:textSize="19dp"
android:textColor="@color/black"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="37dp"
android:layout_marginRight="15dp"
android:background="#C5C0C0" />
<!--数值-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="51dp"
android:layout_marginTop="60dp">
<TextView
android:id="@+id/voltage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="0v"
android:textSize="23dp"
android:textColor="#FFA500"
android:textStyle="bold"/>
<TextView
android:id="@+id/power"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:text="0w"
android:textSize="23dp"
android:textColor="#FFA500"
android:textStyle="bold"/>
<TextView
android:id="@+id/temperature"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:text="0℃"
android:textSize="23dp"
android:textColor="#FFA500"
android:textStyle="bold"/>
</LinearLayout>
<!--文本标识-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="50dp"
android:layout_marginTop="95dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="电 压"
android:textSize="20dp"
android:textStyle="bold"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:text="功 率"
android:textSize="20dp"
android:textStyle="bold"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:text="温 度"
android:textSize="20dp"
android:textStyle="bold"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
</ScrollView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
4、第四步
MainActivity中的代码
public class MainActivity extends AppCompatActivity {
private TextView yunXi;
private ImageView yunXi_point;
private TextView gongZuo;
private ImageView gongZuo_point;
private TextView voltage;
private TextView power;
private TextView temperature;
private WebView echarts_main;
private ScheduledExecutorService scheduler;
private MqttClient client;
private Handler handler;
private String host = "tcp://114.132.152.40:1883";
private String userName = "xiaoluo123";
private String passWord = "xiaoluo123";
private String mqtt_id = "client";//id可同可不同
private String mqtt_sub_topic = "mqtt135";//订阅话题
private String mqtt_pub_topic = "esp135";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
yunXi = findViewById(R.id.yunXi);
yunXi_point = findViewById(R.id.yunXi_point);
gongZuo = findViewById(R.id.gongZuo);
gongZuo_point = findViewById(R.id.gongZuo_point);
voltage = findViewById(R.id.voltage);
power = findViewById(R.id.power);
temperature = findViewById(R.id.temperature);
echarts_main = findViewById(R.id.echarts_main);
echarts_main.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
echarts_main.getSettings().setAllowFileAccess(true); //开启本地文件读取(默认为true,不设置也可以)
echarts_main.getSettings().setJavaScriptEnabled(true); //开启脚本支持
echarts_main.loadUrl("file:///android_asset/index.html");
Mqtt_init();
startReconnect();
handler = new Handler(Looper.myLooper()) {
@SuppressLint("SetTextI18n")
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case 1:
break;
case 2:
break;
case 3:
String receivedMessage = msg.obj.toString();
parseJsonObj(receivedMessage);// 解析接收到的 JSON 数据并更新 UI
System.out.println(receivedMessage); // 显示MQTT数据
break;
case 30:
Toast.makeText(MainActivity.this,"连接失败" ,Toast.LENGTH_SHORT).show();
break;
case 31:
Toast.makeText(MainActivity.this,"连接成功" ,Toast.LENGTH_SHORT).show();
try {
client.subscribe(mqtt_sub_topic,1);
} catch (MqttException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
};
}
// MQTT初始化
private void Mqtt_init()
{
try {
client = new MqttClient(host, mqtt_id,
new MemoryPersistence());
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(false);
options.setUserName(userName);
options.setPassword(passWord.toCharArray());
options.setConnectionTimeout(10);
options.setKeepAliveInterval(20);
//设置回调
client.setCallback(new MqttCallback() {
@Override
public void connectionLost(Throwable cause) {
System.out.println("连接丢失----------");
}
@Override
public void deliveryComplete(IMqttDeliveryToken token) {
System.out.println("完成---------"
+ token.isComplete());
}
@Override
public void messageArrived(String topicName, MqttMessage message)
throws Exception {
System.out.println("消息已到达----------");
Message msg = new Message();
String receivedMessage = message.toString();
updateChart(receivedMessage);
msg.what = 3; //收到消息标志位
msg.obj = message.toString();
handler.sendMessage(msg);
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
// MQTT连接
private void Mqtt_connect() {
new Thread(new Runnable() {
@Override
public void run() {
try {
if(!(client.isConnected()) )
{
MqttConnectOptions options = null;
client.connect(options);
Message msg = new Message();
msg.what = 31;
handler.sendMessage(msg);
}
} catch (Exception e) {
e.printStackTrace();
Message msg = new Message();
msg.what = 30;
handler.sendMessage(msg);
}
}
}).start();
}
// MQTT重连函数
private void startReconnect() {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
if (!client.isConnected()) {
Mqtt_connect();
}
}
}, 0*1000, 10 * 1000, TimeUnit.MILLISECONDS);
}
// 订阅函数
private void publishMessagePlus(String topic,String message2)
{
if (client == null || !client.isConnected()) {
return;
}
MqttMessage message = new MqttMessage();
message.setPayload(message2.getBytes());
try {
client.publish(topic,message);
} catch (MqttException e) {
e.printStackTrace();
}
}
//echarts图表接收数据
private void updateChart(final String receivedData) {
runOnUiThread(new Runnable() {
@Override
public void run() {
echarts_main.evaluateJavascript("updateChartWithData(" + receivedData + ")", null);
}
});
}
// Json数据解析
private void parseJsonObj(String jsonObj){
// 解析json
try {
JSONObject jsonObject = new JSONObject(jsonObj);
String YX = jsonObject.getString("YX");
String GZ = jsonObject.getString("GZ");
String DY = jsonObject.getString("DY");
String GL = jsonObject.getString("GL");
String WD = jsonObject.getString("WD");
//设置文本内容
yunXi.setText(YX);
gongZuo.setText(GZ);
voltage.setText(DY+"v");
power.setText(GL+"w");
temperature.setText(WD+"℃");
// 获取传递给图表的数据
JSONArray oneCOArray = jsonObject.getJSONArray("oneCOValue");
JSONArray methaneArray = jsonObject.getJSONArray("methaneValue");
// 将数据传递给 WebView 更新图表
runOnUiThread(new Runnable() {
@Override
public void run() {
echarts_main.evaluateJavascript("updateChartWithData(" + oneCOArray.toString() + "," + methaneArray.toString() + ")", null);
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
}
5、第五步
MQTTX工具传输即可
{"name":"ESP135","YX":"运行","GZ":"打钻","DY":"37","GL":"21","WD":"37",
"oneCOValue":[21, 22, 33, 14, 55, 66, 77, 88, 99],
"methaneValue":[11, 22, 33, 44, 55, 66, 77, 88, 99]}