环境监测 LED 大屏系统 —— 从 MCU 到 Android 全栈实战(四)Android 客户端
2026/8/14 6:26:25 网站建设 项目流程

App 功能一览

Android 端有 5 个 Tab,分别对应不同功能:

Tab功能效果
看板实时传感器数据卡片 + 趋势图 + 均值11 种传感器网格展示,无数据自动隐藏
发送LED 文本下发多行独立配置,16 种动效,一键温湿度
报警超限报警记录分级显示(危险/预警),可清除
历史历史数据表格最近 120 条,支持 CSV 导出
设置服务器连接 + 报警阈值IP 一键连接测试,配置自动保存

核心架构

MainActivity ├── Tab1: DashboardFragment (数据看板) ├── Tab2: SendFragment (LED发送) ├── Tab3: AlarmFragment (报警记录) ├── Tab4: HistoryFragment (历史数据) └── Tab5: SettingsFragment (系统设置) 共用组件: ├── ApiService (HTTP 单例) ├── SensorData (数据模型) └── TrendChart (自定义折线图)

6 个 Java 文件,零第三方依赖,网络请求都用原生HttpURLConnection

功能一:数据看板怎么实现的?

效果

  • 11 张传感器卡片 2 列排列
  • 彩色顶条区分类型(红=温度、蓝=湿度、紫=VOC)
  • 数值 + 单位 + 更新时间
  • 无数据的传感器自动隐藏卡片
  • 温度/湿度独立折线图
  • 10 点滑动均值统计

实现

数据获取— 每秒轮询一次:

private Runnable poller = new Runnable() { public void run() { if (running) { fetchData(); handler.postDelayed(this, 1000); // 1秒后再来 } } }; private void fetchData() { new Thread(() -> { String json = api.get("/api/data"); // HTTP GET SensorData d = SensorData.fromJson(new JSONObject(json)); getActivity().runOnUiThread(() -> updateUI(d)); // 切主线程更新UI }).start(); }

卡片显隐— 用isNull()精确判断,不用> 0

// SensorData.fromJson() String[] sensorKeys = {"temp","humi","pm10","pm25", "co2","noise","propane","benzene", "xylene","methane","hydrogen"}; for (String k : sensorKeys) d.hasData.put(k, !j.isNull(k)); // JSON null = 无数据 // DashboardFragment.updateUI() for (int i = 0; i < 11; i++) { if (Boolean.TRUE.equals(d.hasData.get(SENSOR_KEYS[i]))) { cards[i].setVisibility(View.VISIBLE); // 有数据显示 tvValues[i].setText(String.format("%.1f", vals[i])); tvTimes[i].setText(d.getTime(SENSOR_KEYS[i])); } else { cards[i].setVisibility(View.GONE); // 无数据隐藏 } }

为什么不用vals[i] > 0?因为温度 0℃ 是合法值,用> 0会误判为“无数据”。

自定义折线图 TrendChart— 纯 Canvas 绘制:

public class TrendChart extends View { private List<Float> data = new ArrayList<>(); private int maxPts = 30; @Override protected void onDraw(Canvas canvas) { // 1. 画网格线和 Y 轴刻度 // 2. 画折线 path // 3. 画半透明渐变填充 // 4. 画数据点圆点 // 5. 每 3 个点标注一次数值 } }

均值统计— 10 点滑动窗口:

if (Boolean.TRUE.equals(d.hasData.get("temp"))) { tempHistory.add(d.temp); if (tempHistory.size() > 10) tempHistory.removeFirst(); tvTempAvg.setText(String.format("%.1f℃", avg(tempHistory))); }

功能二:LED 文本发送怎么实现的?

效果

  • 多行独立配置:文本、坐标、颜色、字号、动效、UID
  • 全部发送:先切页 → 逐行下发
  • 一键温湿度:自动拉取当前数据填到发送行
  • 清除:发空格覆盖,不残留

实现

发送流程

private void sendAll() { // 先切页 api.post("/api/qy-page", "{\"page\":" + page + "}"); Thread.sleep(300); // 等卡切换完毕 // 逐行下发(动画行排后面,避免被立即显示覆盖) lines.sort(立即显示优先); for (line : lines) { api.post("/api/send-text", line.toJSON()); Thread.sleep(200); // 间隔防止丢帧 } }

请求 JSON 示例

{ "text": "温度 21.9 ℃", "x": 4, "y": 0, "color": "white", "font_size": 24, "mode": 1, "uid": 41 }

功能三:服务器连接怎么实现的?

效果

  • 顶部 IP 输入框,格式192.168.1.243:8086
  • 点击连接 → 按钮变绿(成功)或变红(失败)
  • 自动保存到 SharedPreferences
  • 切回看板时自动读取并连接

实现

private void connect(Button btn) { api.setBaseUrl(etIp.getText().toString().trim()); btn.setText("..."); new Thread(() -> { try { api.get("/api/data"); // 测试连通性 runOnUiThread(() -> { btn.setText("已连接"); btn.setBackgroundColor(0xFF22C55E); // 绿色 }); } catch(Exception e) { runOnUiThread(() -> { btn.setText("连接失败"); btn.setBackgroundColor(0xFFE11D48); // 红色 }); } }).start(); }

功能四:报警功能怎么实现的?

效果

  • 超上限:红色标注 danger
  • 低于下限:黄色标注 warn
  • 时间、类型、值、等级列表展示
  • 可一键清除

实现

alarms.forEach(a -> { String bg = a.level.equals("danger") ? "#fef2f2" : // 红色背景 a.level.equals("warn") ? "#fffbeb" : // 黄色背景 ""; // 渲染行... });

功能五:历史数据怎么实现的?

效果

  • 最近 120 条传感器数据表格
  • 时间 + 每类传感器纵向列
  • 导出为 CSV(带 BOM 的 UTF-8,Excel 直接打开不乱码)

实现

String csv = "时间," + 传感器列表 + "\n"; history.forEach(row -> { csv += row.time + ","; for (sensor : sensors) { csv += row.get(sensor) != null ? row.get(sensor) : "-"; csv += ","; } csv += "\n"; }); // \uFEFF = BOM,确保中文在 Excel 中正常显示 new Blob(['\uFEFF' + csv], {type: 'text/csv'});

小结

Android 客户端的设计原则:

  • 懒加载:切到哪个 Tab 才创建对应 Fragment
  • 生命周期感知:onResume 时启动轮询,onPause 时停止轮询,避免后台耗电
  • 原生网络:使用HttpURLConnection,无需第三方库,减少包体积
  • 数据驱动 UI:通过SensorData模型统一管理数据,UI 根据数据状态自动更新
  • 用户体验优先:无数据自动隐藏、连接状态视觉反馈、一键操作

通过以上设计,我们实现了一个轻量、高效、功能完整的 Android 客户端,能够稳定地与 MCU 端进行数据交互,并在 LED 大屏上实时展示环境监测信息。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询