尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Android疫苗预约App开发全流程:期末大作业从设计到打包exe

Android疫苗预约App开发全流程:期末大作业从设计到打包exe 简介这是一份面向安卓初学者的智慧医疗主题期末大作业实践资源聚焦疫苗预约核心功能完整覆盖Android Studio开发全流程助力学生快速掌握移动应用开发关键技能。资源包共121个文件包含21个Java业务逻辑代码、41个XML布局与配置文件、30张JPG运行截图及16张PNG图标资源辅以Gradle构建脚本、APK安装包、可执行EXE导出文件及详尽的Word版设计报告整体压缩后仅6.9MB轻量易部署。已有2813人学习下载报告中嵌入多张真实界面截图与功能说明便于对照理解UI结构、数据流转与模块划分。用户可直接导入Android Studio编译调试复现完整预约流程同时通过设计报告厘清需求分析、架构设计与测试要点是理论结合实践的典型教学案例。 做了个安卓疫苗预约App当期末大作业源码、设计报告、配套的Windows演示工具exe一整套都齐了。这篇文章把我从立项到答辩的完整思路捋一遍包括为什么不接后端、数据库表怎么设计、预约流程图怎么画、号源库存怎么扣、还有配套的Python统计工具怎么用PyInstaller打成exe最后把我在开发过程中踩过的一些坑也一并列出来希望能给正在纠结选题或者卡在某个环节的同学一点参考。先把这个项目本身说清楚这是一款基于Android平台的疫苗预约应用核心功能包括用户注册登录、疫苗信息浏览、按日期选择预约接种、预约记录管理和个人中心配套有一个用Python写的预约数据统计工具负责读取App导出的预约数据文件在Windows上生成统计图表这个工具最终打包成exe文件交付。整体不依赖云端服务器所有数据都存在手机本地SQLite数据库里这对期末大作业来说是最稳妥的方案。它适合以下人群参考选了这个方向但还没有完整思路的同学、想优化自己项目结构和设计报告的同学、以及纠结“exe文件怎么跟安卓App扯上关系”的人。1. 项目整体设计与思路拆解1.1 为什么做疫苗预约这个方向疫苗预约这个选题在智慧医疗大类里属于“看起来专业、做起来可控”的那一类。做期末项目最怕两件事题目太大做不完、题目太小没内容。疫苗预约恰好处于一个平衡点它既有完整的业务闭环登录→浏览→预约→记录→统计又不需要涉及支付、在线问诊、电子病历这类高风险高复杂度模块。从使用场景来说疫苗接种本身就是有明确流程的线下业务用户打开App查看可预约的疫苗种类确认剩余号源后选择接种日期填写接种人信息提交预约到现场出示预约记录完成接种后台再将状态更新为已完成。整套流程天然适合用移动端来实现业务场景清楚评委一看就懂。从课程设计的角度讲疫苗预约App还自带一个加分项——它明显属于“智慧医疗”范畴在题目汇报时能自然联系到公共卫生服务数字化、疫苗接种信息化管理这些方向答辩的时候有话可说。1.2 技术选型本地存储优先不碰云端服务器期末大作业的工期一般就几周如果引入后端服务器意味着你要同时搞定服务端接口开发、数据库部署、服务器租赁、App网络层封装任何一个环节出问题都会拖垮整个项目。所以我的方案是所有数据都存本地SQLite数据库App本身就是一个完整的应用。技术栈选型如下组成部分选型理由开发语言Java课程里教的是Java资料多遇到问题好查UI框架原生XML布局 RecyclerView原生控件稳定避免引入第三方库后版本冲突本地数据库SQLite SQLiteOpenHelperAndroid内置零配置适合本地存储图表生成配套Python工具 matplotlibApp导出的数据文件在PC端做可视化分析打包工具PyInstaller将Python统计工具打包成独立exe文件这里多说一句Java和Kotlin其实都行但如果你对Kotlin不熟千万别在期末阶段临时换语言Java虽然不是最潮的但胜在任何一个报错都能在搜索引擎上找到答案。1.3 “exe文件”到底怎么理解这是很多人一开始会卡住的地方安卓App最终产物是APK文件为什么标题里有“导出exe文件”实际上App本体确实是APK而exe文件是配套的演示分析工具它运行在Windows电脑上。我做这个配套工具的思路是在App的管理员功能里增加一个“导出预约数据”按钮将数据库中的预约记录以JSON或CSV格式导出到手机存储再把文件传到电脑exe工具读取这个数据文件自动生成预约量趋势图、疫苗热度排行、各时间段预约人数分布等统计图表。这个exe工具在答辩现场打开是非常亮眼的操作因为大多数组的演示都只停留在手机屏幕你能把数据用图表形式投到屏幕上展示效果直接上一个台阶。注意安卓App直接打包成exe是不现实的任何声称能把APK直接转成exe的工具都是扯淡。正确的理解是把“演示辅助工具”做成exe这样既符合提交要求又让整个项目看起来更加完整。2. 核心功能模块拆解与数据库设计2.1 功能模块地图整个App按角色分成两类界面普通用户端和管理员端。普通用户端包含注册与登录疫苗列表浏览卡片式展示含疫苗名称、生产厂家、适用人群、价格、剩余号源疫苗详情页副作用说明、接种程序、注意事项预约接种选择接种日期、填写接种人信息我的预约查看预约记录支持取消预约个人中心修改密码、退出登录管理员端包含疫苗管理新增疫苗、编辑疫苗信息、下架疫苗预约管理查看所有用户预约清单按日期筛选标记接种完成数据导出导出预约记录到存储这些功能模块不需要全部做完才叫“完整”你可以根据工期裁剪。我当时是先保证核心流程登录→浏览→预约→我的预约→管理员查看预约再逐步加上疫苗管理和数据导出。2.2 SQLite数据表设计数据库是整个项目的地基表结构设计得合理后面写代码就是水到渠成的事情。我设计了三张表用户表userCREATE TABLE user ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, password TEXT NOT NULL, phone TEXT, role INTEGER DEFAULT 0, -- 0普通用户 1管理员 create_time TEXT DEFAULT (datetime(now,localtime)) );疫苗表vaccineCREATE TABLE vaccine ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, -- 疫苗名称 manufacturer TEXT, -- 生产厂家 applicable TEXT, -- 适用人群 price REAL DEFAULT 0, -- 价格0表示免费 total_stock INTEGER DEFAULT 100, -- 总号源数量 booked_count INTEGER DEFAULT 0, -- 已预约数量 description TEXT, -- 疫苗详细介绍 dosage TEXT, -- 接种程序如“共2剂间隔28天” status INTEGER DEFAULT 1 -- 1上架 0下架 );预约记录表appointmentCREATE TABLE appointment ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL, vaccine_id INTEGER NOT NULL, appoint_date TEXT NOT NULL, -- 预约日期 yyyy-MM-dd patient_name TEXT NOT NULL, -- 接种人姓名 patient_age INTEGER, status INTEGER DEFAULT 0, -- 0待接种 1已完成 2已取消 create_time TEXT DEFAULT (datetime(now,localtime)) );为什么把“剩余号源”拆成“total_stock - booked_count”而不是直接存一个“剩余量”因为预约、取消预约时只需要对booked_count做增减既保留了总号源这个原始信息又避免了减库存时算错。而且这种设计对后面做统计报表很有帮助——你可以知道某个疫苗的总放号量和实际预约量而不是只知道一个模糊的“剩余数”。2.3 字段和状态的细节设计状态字段是我在开发过程中多次踩坑之后特意强调的。预约记录用status区分0、1、2三种状态后台展示时用不同颜色标签区分疫苗的上下架状态用status字段控制下架的疫苗在普通用户端列表里直接不显示。所有时间字段统一用yyyy-MM-dd和yyyy-MM-dd HH:mm:ss格式的文本存储别用Unix时间戳。文本格式在调试时一眼能看懂而且排序就是字符串排序不会出问题。唯一的例外是如果你要按日期范围做聚合统计文本格式稍微麻烦一点但期末项目的数据量级完全不用考虑这个。3. 核心功能实操过程与关键代码3.1 Android项目环境准备我用的是Android Studio官方稳定版编译版本和目标版本选择Android 12API 31以下目的是兼容大多数模拟器避免答辩时因真机系统版本问题没法安装。建议在项目里最低支持版本设为Android 5.0API 21这样覆盖面广而且老的模拟器跑起来也流畅。新建项目时选择Empty Views Activity语言选择Java。不要选Compose虽然Compose很火但如果你不熟调试成本会高很多期末阶段没必要冒险。3.2 登录注册模块的完整实现登录模块是整个App的入口不需要太花哨但逻辑要严谨。注册时校验用户名是否重复、密码长度至少6位、两次密码输入一致全部通过后写入user表。密码用MD5加密后存储虽然是课程设计但明文存密码在答辩时被评委问到会很尴尬。注册功能核心代码简化版public boolean register(String username, String password, String phone) { if (TextUtils.isEmpty(username) || TextUtils.isEmpty(password)) { return false; } SQLiteDatabase db dbHelper.getWritableDatabase(); // 检查用户名是否已存在 Cursor cursor db.rawQuery(SELECT id FROM user WHERE username ?, new String[]{username}); if (cursor.moveToFirst()) { cursor.close(); return false; // 用户名已存在 } cursor.close(); ContentValues values new ContentValues(); values.put(username, username); values.put(password, MD5Util.md5(password)); // MD5加密 values.put(phone, phone); values.put(role, 0); long result db.insert(user, null, values); return result ! -1; }登录时根据用户名查密码判断输入的密码经过MD5加密后是否与数据库一致。管理员账号可以在第一次启动App时预置我是在DBHelper的onCreate里直接插入了一条username为admin、password为admin123MD5值、role为1的记录这样就不用单独写初始化脚本了。3.3 列表展示与详情页疫苗列表用RecyclerView CardView实现每张卡片展示疫苗名称、厂家、剩余号源和预约按钮。这里有个实操要点上架状态的疫苗才显示剩余号源为0时预约按钮置灰。Adapter的getItemCount返回值要注意如果直接用疫苗表的全部数据那么被下架的疫苗也会出现在列表里。所以查询时要带条件String sql SELECT * FROM vaccine WHERE status 1 ORDER BY id DESC;列表刷新的问题也值得单独说当用户从详情页预约成功后返回列表页列表数据必须刷新。我在预约成功后调用finish()回到列表页在列表页的onResume()里重新查询数据库并调用adapter.notifyDataSetChanged()。用onResume而不是onCreate的原因是onCreate只在页面首次创建时执行从详情页返回时不会再走但onResume每次都会执行。3.4 预约流程的实现日期选择与号源扣减预约流程是这个项目的核心业务逻辑要完整从疫苗详情页点击“立即预约”进入预约页面选择接种日期填写接种人姓名和年龄点击提交后完成预约。日期选择我用DatePickerDialog将选中的日期格式化为yyyy-MM-dd存储。这里有一个很关键的细节预约前要检查“该用户是否已经预约过这个疫苗的同一天”否则重复提交会出现数据混乱。检查逻辑很简单在appointment表里查有没有同时满足user_id、vaccine_id和appoint_date三个条件的记录如果有就不允许再约。号源扣减是核心中的核心思路如下查询当前疫苗的booked_count和total_stock判断booked_count total_stock否则提示“该日期号源已约满”插入预约记录更新vaccine表的booked_count加1为了保证这几个步骤的同步操作我用数据库事务包裹db.beginTransaction(); try { // 检查号源 Cursor cursor db.rawQuery( SELECT total_stock, booked_count FROM vaccine WHERE id ? AND status 1, new String[]{String.valueOf(vaccineId)}); if (cursor.moveToFirst()) { int total cursor.getInt(0); int booked cursor.getInt(1); if (booked total) { cursor.close(); return false; // 号源不足 } } cursor.close(); // 插入预约记录 ContentValues values new ContentValues(); values.put(user_id, userId); values.put(vaccine_id, vaccineId); values.put(appoint_date, date); values.put(patient_name, patientName); values.put(patient_age, age); values.put(status, 0); db.insert(appointment, null, values); // 更新号源 db.execSQL(UPDATE vaccine SET booked_count booked_count 1 WHERE id ?, new Object[]{vaccineId}); db.setTransactionSuccessful(); return true; } finally { db.endTransaction(); }事务保证了两点预约记录插入成功号源一定加一号源扣减失败预约记录也不会残留。这是数据库操作的基本素养答辩时评委大概率会问“多人同时预约同一个疫苗怎么办”你把这个代码展示出来说“用事务保证数据一致性”这句话的含金量极高。3.5 我的预约与取消预约预约记录页是一个列表每一条记录显示疫苗名称、接种日期、接种人、当前状态。状态用不同样式的TextView显示待接种是蓝色、已完成是灰色、已取消是红色。取消预约功能的逻辑只有状态为“待接种”的预约才能取消取消时把status改为2同时把疫苗的booked_count减1。这里同样要注意用事务或者至少保证两条SQL要么同时成功要么同时失败。已完成的预约不允许取消因为线下已经接种了。3.6 管理员端功能实现管理员的入口放在登录页下方输入admin账号登录后进入管理界面。管理界面和普通用户端是不同的功能集合疫苗列表显示所有疫苗包括下架的每条记录后有编辑和删除按钮新增疫苗弹出一个表单填写疫苗各项信息预约记录展示全部用户的预约按日期倒序管理员可以标记某条记录为“已完成”管理员功能的代码量不大关键是权限控制。我在每个管理页面的onCreate里检测当前登录用户的role字段如果不是管理员就直接退出到登录页。简单的权限判断虽然不涉及复杂的后台安全模型但至少在应用层面做了角色隔离。3.7 数据导出功能打通App与exe工具在管理员的“预约管理”页面加一个“导出数据”按钮把appointment表和vaccine表关联查询后的结果写入一个CSV文件放到App的外部存储目录。Android 10以上写入公共目录需要申请存储权限所以要在AndroidManifest里声明权限uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE android:maxSdkVersion28/ uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE/这里有个兼容问题Android 11以上对存储权限管理更严格直接用FileOutputStream写到公共目录可能会失败。为了省事我把导出文件写到App私有目录getExternalFilesDir(null)下这个目录不需要存储权限而且通过Android Studio的Device File Explorer能看到用数据线拷出来也很方便。导出代码的核心部分File file new File(getExternalFilesDir(null), appointment_ System.currentTimeMillis() .csv); FileOutputStream fos new FileOutputStream(file); OutputStreamWriter writer new OutputStreamWriter(fos, UTF-8); writer.write(疫苗名称,厂家,接种人,预约日期,状态\n); // 遍历查询结果写入CSV writer.flush(); writer.close();BOM头的问题要提前处理用Excel打开CSV文件时如果文件没有BOM头中文字段会显示乱码。UTF-8的BOM头就是\uFEFF在写入第一行前加上即可writer.write(\uFEFF); // BOM头防止Excel打开中文乱码4. 配套exe统计工具的完整实现流程4.1 这个工具到底做了什么做这个配套工具的需求很直接答辩演示时能快速把你App里的预约数据变成看得见的图表比光翻手机列表有说服力得多。工具的功能设计如下用户选择App导出的CSV文件程序解析CSV数据自动生成三张统计图各疫苗预约次数柱状图按日期统计的预约量折线图各状态待接种/已完成/已取消占比饼图显示总预约量、用户数、疫苗种类数等核心指标技术实现很常规Python tkinter做界面pandas做数据处理matplotlib做图表绘制最后用PyInstaller打包成exe。4.2 核心代码结构主程序main.py的结构import tkinter as tk from tkinter import filedialog, messagebox import pandas as pd import matplotlib.pyplot as plt def select_file(): path filedialog.askopenfilename(filetypes[(CSV files, *.csv)]) if not path: return df pd.read_csv(path, encodingutf-8-sig) show_statistics(df) generate_charts(df) def generate_charts(df): # 疫苗预约量柱状图 df[疫苗名称].value_counts().plot(kindbar) # 预约日期折线图 df[预约日期].value_counts().sort_index().plot(kindline) # 状态占比饼图 df[状态].map({0: 待接种, 1: 已完成, 2: 已取消}).value_counts().plot(kindpie) plt.show()这里有几个细节需要处理状态列在CSV里导出的是数字0、1、2要在pandas里映射成中文再画图日期列排序要用字符串排序因为格式是yyyy-MM-dd文本排序也能得到正确的时间序列。另外matplotlib默认字体不包含中文需要设置中文字体否则图表上会出现方块。plt.rcParams[font.sans-serif] [SimHei] # Windows下使用黑体 plt.rcParams[axes.unicode_minus] False # 正常显示负号4.3 PyInstaller打包exe的完整步骤打包过程不复杂但有几个坑要提前知道。先把PyInstaller装好pip install pyinstaller然后执行打包命令pyinstaller -F -w -i vaccine.ico main.py参数解释-F生成单个可执行文件便于拷贝和提交-w不显示命令行窗口运行GUI程序时避免黑框闪出-i指定exe的图标文件不做商业用途网上找一个疫苗风格的图标即可打包成功后dist目录下会生成main.exe建议重命名为“疫苗预约数据统计工具.exe”。打包过程中最常见的坑第一路径问题。代码里如果用相对路径读取数据文件打包成exe后运行时会报“找不到文件”。这是因为exe解压到临时目录执行工作目录和exe所在目录不同。解决办法是显式读取exe所在目录import sys, os base_path os.path.dirname(sys.argv[0]) if hasattr(sys, frozen) else os.path.dirname(__file__)第二文件体积问题。pandas和matplotlib体积很大打包出来的exe动辄100MB以上。如果觉得太大可以精简依赖比如不用pandas直接用csv模块手动解析这样exe可以小到40MB左右。期末答辩对体积没有硬性要求我建议保留pandas因为代码更简洁编写和维护省时间。第三杀毒软件误报问题。PyInstaller打包的exe有时会被Windows Defender或一些第三方杀毒软件误报这不是病毒是因为PyInstaller打包的文件结构特征。提前在答辩用的电脑上测试运行最好关掉实时防护或者加入白名单。5. 常见问题与排查技巧实录5.1 数据库相关的典型问题问题一数据库升级后原有的表结构没变新加的字段查不到。这个通常是因为SQLiteOpenHelper的onUpgrade没有正确执行设备上还保留着旧版本数据库文件。调试阶段最简单的处理方式是卸载App重装或者把App的数据清除。如果是在开发后期才发现就手动删掉数据库文件再重新创建。问题二RecyclerView列表刷新后数据不更新。我遇到的主要原因是新数据插入数据库后Adapter还在用旧数据集。排查思路先确认查询语句执行了再确认notifyDataSetChanged调用了最后确认数据集是新的List而不是同一个对象的引用。用onResume刷新是通用解法。问题三并发操作导致的SQLiteDatabaseLockedException。这个在单机App上并不常见但如果你的异步任务里有多个方法同时操作数据库就有可能触发。我建议所有数据库操作都走同一个SQLiteOpenHelper实例并且不在子线程和主线程同时访问数据库能避免绝大多数锁问题。5.2 编译和运行问题问题一Error: Unable to find method annotateMe. 这种问题通常是编译环境不一致导致的解决办法是全量Clean Project然后Rebuild Project。问题二安装到真机失败报INSTALL_FAILED_OLDER_SDK说明App的minSdkVersion设置得比手机系统版本高。把minSdkVersion调低一点或者直接使用Android Studio自带的模拟器。问题三模拟器上App运行慢卡顿。这是老模拟器的通病建议Host GPU模式开启或者换用Android Studio的ARM镜像。如果电脑配置一般直接连真机调试开发速度和运行流畅度都会更好。5.3 打包APK时要注意的签名问题答辩前要提交APK安装包别人拿到的必须是签名后的正式版APK。Android Studio默认使用的debug签名只能用于开发调试部分手机安装时会提示风险。生成签名APK的路径Build → Generate Signed Bundle / APK → APK → Create new keystore填写信息后完成签名。签名文件.jks一定要保存好后面更新APK必须用同一个签名文件换签名会导致旧用户无法覆盖安装。这个在答辩场景可能不明显但如果你后续继续完善项目这就是必修课。5.4 设计报告的撰写要点设计报告是期末项目评分的重要部分很多人只注重代码忘了写报告其实报告写好了能顶半边天。我建议报告结构如下项目背景与意义公共卫生服务信息化、疫苗接种预约管理的痛点需求分析功能需求、性能需求、用户角色系统设计功能模块图、系统架构图、数据库E-R图、界面原型核心功能实现关键代码和逻辑说明不需要贴全部代码挑重点讲系统测试功能测试用例表包括输入、预期输出、实际输出、是否通过总结与展望项目完成度、不足、后续可以怎么扩展报告里一定要有图。功能模块图、流程图、E-R图这三项是减分重灾区只要不缺剩下的内容哪怕平铺直叙也很容易过。画图可以用PowerPoint自带形状或者draw.io免费在线画不需要太高深的设计功底。5.5 答辩演示的实操建议答辩现场最忌临时演示出问题。我的建议是准备一个模拟器作为主演示环境同时一台真机备着。模拟器可以提前调好窗口大小确保现场投屏时缩放比例合适。真机则要提前关掉锁屏密码、调整休眠时间为永不防止演示到一半熄屏。演示顺序上按“注册→登录→浏览疫苗→预约→我的预约→取消预约→管理员登录→查看预约→导出CSV→打开exe工具→展示统计图表”这条流程走一遍基本能覆盖项目所有功能点全程大约五六分钟。这套流程走下来评委至少会认为这是一个完成度很高的项目而不仅仅是个课程作业。最后分享一点体会整个项目从前期的选题规划到最终答辩我最想提醒后来者的一件事就是不要最后一周才开始写报告。代码写完了、功能跑通了再去补文档很容易懒得写写出来的东西也就没什么质量。更好的做法是开发过程中顺手截图、记录关键决策、保存测试数据每周抽一两个小时往报告里填内容到交之前只需要整理润色。这个习惯不仅适用于期末大作业以后做毕业设计、实习项目汇报也用得上。另外项目里的一些细节在答辩时真心加分事务保证号源一致、密码MD5加密存储、CSV文件加BOM头防Excel乱码、PyInstaller打包exe供Windows端统计分析这些都是在学校课程里不会专门讲、但实际项目里一定会遇到的东西。把它们写进报告是你和普通学生作业拉开差距的关键。如果后续有时间你还可以在这个项目基础上扩展儿童疫苗计划提醒、接种留观倒计时、疫苗溯源信息查询等功能学到的数据库设计和业务拆分思路都能直接复用进去。本文还有配套的精品资源点击获取
返回列表