恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Android煤矿调度管理系统:Web API与SQL Server端到端实践

  • 首页
  • 资讯中心
  • /
  • Android煤矿调度管理系统:Web API与SQL Server端到端实践

相关资讯

libstdc++.so.6与GLIBCXX版本不匹配?从定位到解决的完整排查指南 2026/9/17 16:30:01
挑战杯获奖docx解析入库:OOXML、合并单元格与SQLite检索 2026/9/17 16:30:01
Linux服务器巡检Shell脚本:资源、账号与cron实战 2026/9/17 16:30:01

最新资讯

Potpie CLI 完全参考:上下文图命令体系的用法与源码级剖析
VueFieldApi 接口解析:深入 TanStack Form Vue 字段 API 的类型体系与响应式实现
yaml-cpp 随附的 Googletest 1.16 官方样例详解:从 TEST 宏到监听器与反射 API
DeepSeek 指令公式模板化:四段式结构、批量调用与 PDF 导出
Agent Governance Toolkit Go SDK 全栈组合实战:用 GovernOperation 串联身份、策略、熔断与审计七子系统
元器件可靠性降额准则一览:从应力模型到选型校验实践

今日推荐

每日热评|13% 的 Agent 技能带严重漏洞,这个注册表想用“验证+签名”解决信任危机
即梦AI保姆级教程:从生图到数字人,一站式搞定AI视频创作
BERT+LLM混合架构:突破NER长尾实体抽取瓶颈的工程实践

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

Android煤矿调度管理系统:Web API与SQL Server端到端实践

发布时间:2026/9/17 16:30:01
Android煤矿调度管理系统:Web API与SQL Server端到端实践 简介这份资源是《基于Android的煤矿调度管理系统设计》的技术文献PDF面向移动应用开发学习者、计算机专业学生及煤矿信息化从业人员用于了解如何用Android客户端结合ASP.NET MVC4框架下的Web API与Java技术构建可随时随地查看矿井环境信息与生产情况的移动调度系统。资源包内含1个PDF文件约465KB篇幅精炼适合作为课程设计、毕业设计选题或行业信息化改造的参考文献。文中围绕调度通知、生产日报、生产计划、安全监测、人员定位与安全管理等功能模块展开讲解客户端与服务端通过HTTP连接、以JSON轻量格式交换数据的设计思路并涉及人员定位、瓦斯检查、交接班记录、掘进进尺等业务数据的组织方式同时分析了移动平台相较传统PC与局域网系统在实时性和访问灵活性上的优势。目前已有99人学习可为读者提供系统架构参考、技术选型依据与调度业务梳理思路帮助快速把握移动端煤矿调度管理系统的实现要点与开发脉络。1. 从 PC 调度台到掌上终端Android 煤矿调度管理系统要解决什么调度室里最常见的一幕是墙上挂一排电话桌上摊着交接班记录本瓦斯检查、掘进进尺、干部下井这些数据靠人工抄写再回到 PC 上的局域网系统里录一遍。领导想看昨天北翼回采面的原煤产量和日计划进尺得等调度员把日报汇总完才能打印出来中间隔着几个小时的信息延迟。这套基于 Android 的煤矿调度管理系统干的就是把这段链路搬到手机上。客户端用 Java 写服务器端用 ASP.NET MVC4 框架下的 Web API 提供 REST 接口业务数据落在 SQL Server 2008两端用轻量级 JSON 交换。调度通知、生产日报、生产计划、安全监测、统计分析、人员定位、安全管理七个模块各自独立成一条数据通道。它适合两类人一类是煤矿信息化岗的工程师手上有现成的 PC 端系统想加移动端另一类是做 Android 客户端开发、需要一套完整「客户端 Web API 数据库」闭环练手的开发者。前者关心接口怎么和已有库对齐后者关心工程能不能跑起来。2. 端到端的通信骨架Android 客户端、Web API 与 SQL Server 怎么分层2.1 移动端为什么落在 Android 上原文给出的理由很直白Android 开源、机型选择多、终端价格低适合煤炭行业大批量配发。这条判断放到今天依然成立但落点变了——当年用 Eclipse ADT现在统一走 Android Studio Gradle。这个迁移不是换个 IDE 那么简单build.gradle里的compileSdk、minSdk、targetSdk三个值直接决定了你能不能装到矿上那批还在跑的旧机器上。我一般的取值是minSdk定 19Android 4.4因为不少工业三防机和低价商用机还停在这个版本targetSdk跟着当时的稳定版走但要注意 Android 6.0 之后的运行时权限、7.0 之后的file://限制、9.0 之后的明文 HTTP 限制这三条会在真机上直接卡住你。矿区内网接口如果还是http://就得在network_security_config.xml里显式放行域名否则请求会被系统拦掉日志里只留一句CLEARTEXT communication not permitted。另一个现实问题是分发。Android 允许自签名 APK 内网直装不需要走应用商店审核这对煤矿这种封闭环境是刚需。代价是签名文件必须自己管好丢了就没法覆盖升级。2.2 客户端—Web API—SQL Server 的三段式数据流整个系统就三段任何一次数据请求都沿这三段走一遍Android 客户端拼装 URL 和查询参数建立 HTTP 连接Web API 控制器收到请求校验参数拼装参数化 SQL交给 SQL Server 执行结果集映射成实体对象序列化成 JSON沿 HTTP 响应回到客户端客户端解析后渲染到列表或图表上。客户端和服务器之间只走 GET/POST/PUT/DELETE 四个 REST 动词不用自定义协议。这样接口天然可缓存、可用 Postman 或 curl 直接验排查问题时能把「是客户端的问题还是服务端的问题」一刀切开。附件下载是个例外。调度通知里的 EXCEL、文本附件不走 JSON而是单独开一个静态文件接口或下载端点客户端拿到 URL 后用DownloadManager拉取再交给系统组件打开。2.3 接口契约REST 动词与 JSON 字段约定七个模块如果各写各的返回格式客户端会写疯。常见做法是统一响应体外层固定code、msg、data三个字段业务数据一律塞进data客户端只写一套解析逻辑。模块请求方法与路径关键参数返回内容生产计划-回采GET /api/StopePlanJHYF、DWStopePlan 数组生产计划-掘进GET /api/ExcavatePlanJHYF、DWExcavatePlan 数组生产日报GET /api/DailyReportDate、OrgId原煤/精煤产量、进尺安全监测GET /api/SafetyMonitorDate、Type模拟量/开关量数组人员定位GET /api/PositionDate井下总人数、干部人数统计分析GET /api/StatisticRange、OrgId序列化图表数据调度通知GET /api/NoticePageIndex、PageSize通知分页列表响应体大概长这样注意数值型字段不要加引号否则客户端求和时会踩坑{ code: 0, msg: ok, data: [ { GZMBH: HC101, GZMMC: 北翼回采面, JHYF: 2024-06, YJHCL: 12000, RJHCL: 400, SCTS: 25 } ] }2.4 开发环境落位Android Studio、SDK 与调试通道环境这步最容易被低估。命令行装 SDK 比图形界面点选可控得多也便于在一台新机器上复现# 列出可用的平台与构建工具确认版本号再下载 sdkmanager --list | grep -E platforms;android-|build-tools # 只装项目真正需要的避免整包下载拖慢环境搭建 sdkmanager platforms;android-34 build-tools;34.0.0 platform-tools # 确认设备已被识别-l 会打印机型、系统版本和连接方式 adb devices -l第一条命令里的--list只读不写可以放心跑grep过滤是为了在几百行输出里定位平台包名格式固定为platforms;android-API 级别。第二条命令的引号不能省分号在 shell 里是命令分隔符。第三条的-l比裸adb devices多出设备型号和transport_id真机连不上时先看这里有没有unauthorized——那说明手机上还没点「允许 USB 调试」。环境跑通之后建议先用一个空 Activity 打包安装到真机上确认签名、权限、网络三件事都正常再往里填业务代码。3. 服务端实现从 productionStopePlan 表到 Web API 控制器3.1 用实体类承接数据库字段生产计划模块定义了四张表productionStopePlan回采工作面月计划、productionExcavatePlan掘进工作面月计划、productionYearPlan年度原煤/精煤计划、productionMonthPlan月度原煤与进尺计划。每张表对应一个 C# 实体类放在Models文件夹下。namespace MobileAPI.Models { public class StopePlan { public string GZMBH { get; set; } // 工作面编号主键之一 public string GZMMC { get; set; } // 工作面名称 public string DW { get; set; } // 单位主键之一 public string JHYF { get; set; } // 计划月份主键之一 public string SGDW { get; set; } // 施工单位 public int SCTS { get; set; } // 月生产天数 public decimal YJHJC { get; set; } // 月计划进尺 public decimal RJHJC { get; set; } // 日计划进尺 public decimal YJHCL { get; set; } // 月计划产量 public decimal RJHCL { get; set; } // 日计划产量 public DateTime KSSJ { get; set; } // 预计开始时间 public DateTime JSSJ { get; set; } // 预计结束时间 } }这里有个坑值得单独说原文把日期字段定义成string编译能过但序列化出去就是数据库原始格式客户端拿到2024/6/1 0:00:00这种字符串还得自己截。改成DateTime后Web API 默认按 ISO 8601 输出配合客户端SimpleDateFormat(yyyy-MM-dd)转换更稳。数值字段同理Float换成decimal能避免产量累加时的精度漂移——几万块的月计划产量差个零点几吨报表上就对不上。3.2 参数化 SQL 与 GetList(JHYF, DW) 方法回采工作面月计划有两个业务主键计划月份JHYF和单位DW。接口方法就按这两个参数取值返回。public IQueryableStopePlan GetList(string JHYF, string DW) { ListStopePlan list new ListStopePlan(); string strSql SELECT JHYF, OrgId, GZMBH, GZMMC, SGDW, SGFZR, SCTS, YJHJC, RJHJC, YJHCL, RJHCL, KSSJ, JSSJ FROM SCHCGZMYJHB WHERE FLAG 0 AND JHYF JHYF AND OrgId OrgId; // 参数化杜绝字符串拼接带来的注入风险 SqlParameter[] parameters { new SqlParameter(JHYF, SqlDbType.VarChar) { Value JHYF }, new SqlParameter(OrgId, SqlDbType.VarChar) { Value DW } }; using (SqlDataReader reader SqlHelper.ExecuteReader(strSql, parameters)) { while (reader.Read()) { list.Add(new StopePlan { JHYF reader[JHYF].ToString(), GZMBH reader[GZMBH].ToString(), GZMMC reader[GZMMC].ToString(), SCTS Convert.ToInt32(reader[SCTS]), YJHCL Convert.ToDecimal(reader[YJHCL]), RJHCL Convert.ToDecimal(reader[RJHCL]) }); } } return list.AsQueryable(); }FLAG 0是逻辑删除标记查询计划数据时必须带上否则作废的历史计划会混进列表客户端看到重复工作面还以为是接口出错了。SqlDbType.VarChar显式声明类型避免 SQL Server 隐式转换导致索引失效——表大起来这个差别很明显。using包住SqlDataReader是必须的连接池的连接数有限漏掉一次释放并发几十个请求后接口就会开始超时。3.3 路由配置与统一响应体MVC4 的 Web API 默认路由模板是api/{controller}/{id}只有一个可选参数位。但业务方法叫GetList(string JHYF, string DW)两个参数默认路由根本匹配不到。解决办法是在WebApiConfig里加上 action 段public static class WebApiConfig { public static void Register(HttpConfiguration config) { // 允许按方法名路由多参数接口才能落到 GetList / GetDetail 上 config.Routes.MapHttpRoute( name: DefaultApiWithAction, routeTemplate: api/{controller}/{action}/{id}, defaults: new { id RouteParameter.Optional } ); // 强制 JSON 输出去掉 XML 格式化器 config.Formatters.Remove(config.Formatters.XmlFormatter); // 日期统一按 yyyy-MM-dd 输出省掉客户端的字符串截取 var json config.Formatters.JsonFormatter; json.SerializerSettings.DateFormatString yyyy-MM-dd; } }加 action 段之后 URL 变成/api/StopePlan/GetList?JHYF2024-06DWHC101语义更清楚也方便在同一个控制器里放多个查询方法。Remove(XmlFormatter)那行经常被忽略不删掉的话客户端请求头里带Accept: application/xml时会拿到 XML而 Android 侧只写了 JSON 解析逻辑直接崩在解析那一行。统一响应体建议包一层public class ApiResultT { public int code { get; set; } // 0 成功非 0 为业务错误码 public string msg { get; set; } // 面向客户端的提示语 public T data { get; set; } // 业务数据可为 null }错误码分段管理1xx 参数错误2xx 数据不存在5xx 服务端异常。客户端拿到非 0 的 code 直接弹msg不用再猜。3.4 分页、时间范围与批量查询的扩展调度通知这类列表必须分页一次拉全量在弱网下体验极差。SQL Server 2008 有个硬限制不支持OFFSET ... FETCH那个语法要 2012 才有。2008 上只能靠ROW_NUMBER()-- 按发布时间倒序分页Start 和 End 由 PageIndex、PageSize 换算 SELECT * FROM ( SELECT ROW_NUMBER() OVER (ORDER BY FabuTime DESC) AS rn, Id, Title, FabuTime, Type, FileUrl FROM Notice WHERE FLAG 0 AND OrgId OrgId ) t WHERE t.rn BETWEEN Start AND End;换算关系是Start (PageIndex - 1) * PageSize 1End PageIndex * PageSize。子查询里的ORDER BY决定了「第几页」的定义写错排序字段会出现翻页数据重复。安全监测的历史查询走的是时间范围而不是分页参数是Date加Type模拟量/开关量。这里要注意索引如果MonitorDate上没有索引查一个月的历史数据会走全表扫描几百毫秒能拖到几秒。常见做法是在(OrgId, MonitorDate, Type)上建联合索引。4. Android 客户端落地网络请求、JSON 解析与七个功能模块4.1 网络层封装HttpURLConnection、超时与重试七个模块的请求逻辑高度相似抽一个工具类出来别在每个 Activity 里重复写。核心是三点超时、线程、进度反馈。public class ApiClient { private static final int CONNECT_TIMEOUT 8000; // 建连超时矿区弱网要放宽 private static final int READ_TIMEOUT 15000; // 读超时报表接口数据量大 public static void get(final String url, final ApiCallback callback) { new Thread(new Runnable() { Override public void run() { HttpURLConnection conn null; try { conn (HttpURLConnection) new URL(url).openConnection(); conn.setRequestMethod(GET); conn.setConnectTimeout(CONNECT_TIMEOUT); conn.setReadTimeout(READ_TIMEOUT); conn.setRequestProperty(Accept, application/json); int code conn.getResponseCode(); if (code 200) { String body readStream(conn.getInputStream()); callback.onSuccess(body); } else { callback.onFailure(HTTP code); } } catch (Exception e) { callback.onFailure(e.getMessage()); } finally { if (conn ! null) conn.disconnect(); } } }).start(); } }HttpURLConnection在不引入第三方库的情况下够用connectTimeout管的是 TCP 握手readTimeout管的是数据回传两个都要设。矿区井下网络抖动厉害8 秒建连、15 秒读是偏保守的取值如果接口本身响应很快可以把读超时压到 6 秒失败后重试一次比干等更友好。回调必须切回主线程再更新 UI。runOnUiThread或者Handler都行直接在工作线程里动TextView会抛CalledFromWrongThreadException。4.2 JSON 解析与实体映射拿到响应体后先判code再取data。这一步的健壮性决定了 App 会不会因为一个字段就闪退。public static ListStopePlan parseStopePlan(String resp) throws JSONException { ListStopePlan list new ArrayList(); JSONObject root new JSONObject(resp); if (root.optInt(code, -1) ! 0) { throw new JSONException(root.optString(msg, 接口返回异常)); } JSONArray arr root.optJSONArray(data); if (arr null) return list; // data 为 null 时返回空列表不抛异常 for (int i 0; i arr.length(); i) { JSONObject o arr.getJSONObject(i); StopePlan p new StopePlan(); // optXxx 系列在字段缺失时返回默认值比 getXxx 更适合现场数据 p.setGZMBH(o.optString(GZMBH)); p.setGZMMC(o.optString(GZMMC)); p.setYJHCL((float) o.optDouble(YJHCL, 0)); p.setRJHCL((float) o.optDouble(RJHCL, 0)); list.add(p); } return list; }关键差异在optString和getString现场历史数据常有字段为空的情况getString遇到null直接抛JSONException整个列表页白屏。用opt系列并把data为null的情况兜成空列表客户端至少能显示「暂无数据」。如果项目里已经引入 Gson用SerializedName映射字段名更省事代价是混淆时必须给实体类加-keep否则发布版字段名被改解析全废。4.3 列表与图表生产日报、统计分析怎么画七个模块里调度通知、生产计划、人员定位、安全管理本质都是列表用RecyclerView加一个通用Adapter就能覆盖。真正需要单独设计的是统计分析模块它要画三种图图表类型对应数据横纵轴折线图一周煤炭数据走势X 为日期Y 为产量柱状图年、月数据对比X 为周期Y 为计划量/完成量饼图日生产数据构成各煤种占比图表库选型上老项目常用 AChartEngine新一点的是 MPAndroidChart后者维护活跃、支持手势缩放。折线图要注意数据点为空的情况某天没有上报产量接口返回的数组里缺一个点直接连起来会把走势画平正确做法是在客户端补 0 或者断线处理别让领导看到一条假的平滑曲线。列表加载时配一个进度条让用户知道请求发出去了。转圈的位置放在列表上方不要用模态对话框——矿区信号不稳转圈可能要持续十几秒模态框会挡住用户返回。4.4 附件下载、FileProvider 与进度提示调度通知里的 EXCEL 和文本附件是最容易被忽略的一块。下载用DownloadManager它自带通知栏进度DownloadManager.Request req new DownloadManager.Request(Uri.parse(fileUrl)); req.setTitle(noticeTitle); req.setNotificationVisibility( DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); req.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, fileName); DownloadManager dm (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); dm.enqueue(req);真正的坑在「打开」这一步。Android 7.0 开始应用之间传递file://会抛FileUriExposedException必须换成content://。做法是在AndroidManifest.xml里注册 FileProviderprovider android:nameandroidx.core.content.FileProvider android:authoritiescom.coalmine.dispatch.fileprovider android:exportedfalse android:grantUriPermissionstrue meta-data android:nameandroid.support.FILE_PROVIDER_PATHS android:resourcexml/file_paths / /providerfile_paths.xml里声明允许共享的目录external-files-path对应上面setDestinationInExternalFilesDir的落盘位置两边必须对上否则打开附件时报IllegalArgumentException: Failed to find configured root。生成 URI 时用FileProvider.getUriForFile(context, com.coalmine.dispatch.fileprovider, file)再配Intent.FLAG_GRANT_READ_URI_PERMISSION交给系统打开。4.5 签名、SHA1 与真机调试发布前第一件事是确认签名。用 keytool 直接读# 查看签名文件的 SHA1 指纹用于第三方 SDK 注册和设备白名单 keytool -list -v -keystore release.jks -alias coalmine -storepass 你的密码输出里的SHA1和MD5两行要抄下来存档后续接地图、推送之类的服务都会要。注意 debug 签名和 release 签名生成的指纹完全不同本地调试正常、打包后白屏八成是这里没对上。真机调试建议开adb无线连接矿上测试不可能每次都插数据线。混淆规则里至少要保住实体类和 JSON 解析相关的类-keep class com.coalmine.dispatch.model.** { *; }一行能省掉几小时的排查。5. 联调与验证接口连通性、日志定位与弱网处理的实战技巧5.1 用命令行先验接口再联客户端客户端报错时第一步不是改 Java 代码而是确认服务端到底返回了什么。curl 最直接# -i 打印响应头-w 追加耗时统计方便判断是接口慢还是网络慢 curl -i -s -w \n耗时: %{time_total}s\n \ http://10.0.1.20:8080/api/StopePlan/GetList?JHYF2024-06DWHC101 \ -H Accept: application/json如果这里返回的是 HTML 错误页或 XML说明路由或格式化器配置有问题客户端再怎么写都没用。如果 curl 正常而 App 异常问题就在客户端直接跳到 logcat 那一节。5.2 adb logcat 与关键日志位日志加了标签才好过滤。网络层统一打DispatchNet崩溃看AndroidRuntime# 只看自定义网络日志和崩溃栈-s 相当于把其他标签静音 adb logcat -s DispatchNet:V AndroidRuntime:E # 需要看完整上下文时把结果落到文件再慢慢翻 adb logcat -d dispatch_$(date %Y%m%d_%H%M).log习惯上会把请求 URL、响应码、响应体前 500 字符打出来。响应体截断很重要——安全监测接口一次可能返回上千条记录全量打进日志会拖慢 App也会把关键信息冲掉。5.3 中文乱码、时间格式与空数据的三个高频坑现象根因处理方式工作面名称显示成乱码响应头未声明字符集Web API 侧统一 UTF-8客户端readStream按 UTF-8 解码日期显示2024-06-01T00:00:00未配置序列化格式JsonFormatter.SerializerSettings.DateFormatString指定 yyyy-MM-dd列表页白屏无提示data返回 null解析抛异常服务端空结果返回[]客户端optJSONArray兜底第三条最容易被忽视。SQL 查询没有命中记录时list.AsQueryable()序列化出来是[]而不是null但如果中间做了对象包装又忘了判空就可能变成null。约定好「列表接口永远返回数组哪怕是空数组」客户端就只需要写一套逻辑。5.4 弱网与超时的处理策略矿区井下到地面的链路经常断客户端要有明确的失败语义。我的做法是请求失败后延迟 2 秒自动重试一次两次都失败才提示用户「网络异常请稍后重试」同时把最后一次成功的响应缓存到本地 SQLite断网时列表仍能展示上一次的数据。服务端侧则要控制单次返回的数据量。安全监测的历史数据按天查如果一天有几千条记录接口响应体可能到几兆弱网下基本读不完。分页参数不只是列表接口的事历史数据接口同样要加PageSize默认 200 条封顶客户端滚动到底再拉下一页。最后一个细节Android 9.0 之后默认禁止明文 HTTP矿区内网接口如果还没上 HTTPS必须在AndroidManifest.xml的application节点加android:usesCleartextTraffictrue或者用network_security_config.xml只对指定内网域名放行——前者图省事但范围太大后者多写几行配置安全性可控得多。本文还有配套的精品资源点击获取

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号