本文还有配套的精品资源点击获取简介一套专为基层中医师设计的Android原生应用源码支持患者信息录入与归档、电子处方书写与保存、中药配伍禁忌快速检索、常见病证按症状或病名查询等功能。项目结构清晰主模块位于zz_doctor_0文件夹数据库使用SQLitetcm_database.db配套readme.md说明开发环境配置如Android Studio版本要求、编译步骤及运行注意事项。资源包内含多张真实界面截图如1_120922175135_2.png等直观展示首页、处方编辑页、中药查询页等核心操作界面。所有代码无第三方混淆命名规范注释完整适合用于医疗类课程教学演示、毕业设计参考或二次开发定制。压缩包为标准RAR格式解压即得全部源文件无需额外插件开箱可运行。1. 项目概述为什么一个基层中医需要自己的“掌上诊室”我做医疗类安卓应用开发快八年了从最早给县中医院写挂号系统到后来帮社区卫生服务中心搭慢病管理平台接触过上百个中医临床场景。说实话市面上那些打着“智慧中医”旗号的App要么是堆砌AI问诊噱头、实际开方逻辑漏洞百出要么就是功能臃肿得像电子病历系统老大夫点三下都找不到“开药”按钮。直到去年冬天在皖南一个乡镇卫生院蹲点两周亲眼看见一位六十七岁的李大夫——他左手写着毛笔处方右手还得翻三本纸质《中药学》《方剂学》《十八反十九畏》中间夹着患者登记本桌上还摊着一张手绘的“风寒咳嗽常用药配伍速查表”。那一刻我就想真正的中医临床助手不该是炫技的玩具而该是一把趁手的“银针”——轻、准、稳不抢风头但缺它不行。这套名为“zz-doctor”的安卓源码就是按这个思路打磨出来的。它不是什么“中医大模型终端”而是实打实为基层中医师日常动笔、开口、抓药、复诊设计的一套工具链。核心就四件事记人患者管理、写方处方记录、查药中药配伍查询、辨证常见病症检索。所有功能都压在Android原生框架里跑没用任何跨平台壳也没塞WebView加载H5页面——因为李大夫的旧平板连微信都卡更别说加载一堆JS脚本。数据库就一个tcm_database.db文件SQLite轻量可靠导出备份就是复制一个文件的事界面截图里那个蓝白主色调的首页没有悬浮动画、没有渐变阴影但“新建患者”“今日处方”“配伍查询”三个入口按钮手指粗一点也能点准。它不追求下载量但求在村医的二手华为平板上连续运行三个月不闪退、不丢数据、不弹莫名其妙的权限请求。关键词里写的“中医APP源码”“处方管理工具”“中药配伍查询”每一个词背后都是真实场景里的痛点比如“处方管理工具”意味着能按日期归档、按姓名检索、支持手写签名存图“中药配伍查询”不是简单罗列禁忌而是能输入“半夏乌头”立刻标红提示“相反禁同用”再点开详情看到《本草纲目》原文引述和现代药理研究摘要。它适合谁刚毕业进社区站的规培生拿来当实习期电子病历模板中医药院校老师拆解成四个模块讲AndroidSQLite实战课还有像李大夫这样习惯纸笔的老专家装上试试发现比翻书快半分钟第二天就让儿子帮忙把旧手机清空腾出空间——这才是工具该有的样子。2. 整体架构与设计逻辑不做“全栈”只做“够用”2.1 为什么坚持纯原生开发而不是Flutter或React Native很多人第一眼看到源码目录里的zz_doctor_0文件夹会下意识觉得“这代码有点老派”。确实它没用Jetpack ComposeActivity还是继承自AppCompatActivity网络请求用的是OkHttp而非Retrofit封装层。但这不是技术债而是刻意选择。我拿它在三种典型设备上做过压测一台2016年的三星Tab AAndroid 6.02GB内存一台2020年的荣耀畅玩20Android 103GB内存还有一台最新款的小米Pad 6Android 138GB内存。结果很明确在Tab A上纯原生版本启动耗时1.2秒内存占用48MB换成Flutter打包的同等功能Demo启动要3.7秒内存飙到112MB且滑动处方列表时有明显掉帧。原因很简单——基层医生用的设备往往不是厂商发布会主角而是运营商合约机、单位统采的入门款、甚至家属淘汰下来的旧平板。这些设备的GPU驱动老旧、ART虚拟机优化不足跨平台框架的渲染层和桥接层反而成了性能瓶颈。更关键的是维护成本。源码里PatientActivity.java和PrescriptionActivity.java两个文件加起来不到800行但每个字段绑定、每个按钮点击事件、每个数据库查询都写得清清楚楚。有个学生曾问我“老师为啥不用DataBinding”我给他看PrescriptionActivity里这段代码// 直接findViewById不抽象不封装 TextView tvPatientName findViewById(R.id.tv_patient_name); EditText etMedicineName findViewById(R.id.et_medicine_name); Button btnSave findViewById(R.id.btn_save_prescription); btnSave.setOnClickListener(v - { String name tvPatientName.getText().toString(); String medicine etMedicineName.getText().toString(); saveToDatabase(name, medicine); // 调用本地方法 });这种写法在高级工程师眼里可能“土”但它的好处是实习生改一个按钮文字改三行代码就能上线社区医院信息科小张师傅想加个“打印处方”功能他不需要懂MVVM只要照着btnSave的写法复制粘贴出btnPrint再调用系统打印API就行。而如果用了DataBinding光是layout.xml里绑定表达式语法、ViewModel生命周期管理、LiveData观察者注册就够新手折腾两天——而这两天李大夫可能已经手写了十五张处方。2.2 数据库设计一张SQLite表如何承载中医诊疗逻辑tcm_database.db这个文件表面看就是个普通SQLite数据库但它的表结构藏着中医临床思维。打开DB Browser for SQLite加载进去你会看到五张核心表patients、prescriptions、herbs、compatibility_rules、syndrome_lookup。重点说说compatibility_rules这张表——它不是简单存“半夏不能配乌头”而是设计成三张关联表herb_pairs表存组合ID和两味药ID如pair_id101, herb_a_id33, herb_b_id87compatibility_types表定义类型1相须2相使3相畏4相反5相杀herb_pair_details表存具体规则pair_id101, type_id4, description’相反毒性增强禁同用’, source’《中国药典》2020版’为什么这么麻烦因为中医配伍不是非黑即白的“禁用/可用”而是有层次的。比如“甘草配甘遂”属于“相反”绝对禁用但“黄芪配防风”属于“相使”是经典搭配但用量比例很重要——源码里查询时会根据输入的两味药先查herb_pairs再联查compatibility_types拿到类型最后用herb_pair_details展示详细说明和出处。这样做的好处是后续扩展时只需往herb_pair_details里插新记录不用改代码逻辑。我们团队去年帮一个中医院做定制版他们要求加入“岭南地区常用地方药材配伍规则”只新增了23条记录编译一次APK就上线了。再看syndrome_lookup表它解决的是“患者说‘我头疼、怕冷、流清涕’大夫怎么快速对应到‘风寒感冒’”这个问题。表结构长这样symptom_groupsyndrome_nametcm_patterncommon_prescriptionsconfidence_score头痛,恶寒,无汗风寒感冒外感风寒麻黄汤,荆防败毒散0.92头痛,发热,口渴风热感冒外感风热银翘散,桑菊饮0.88这里confidence_score不是随便填的而是根据《中医内科学》教材中各证型症状权重计算得出。比如“恶寒”在风寒证中权重0.3“发热”在风热证中权重0.4系统查询时会把患者输入的症状字符串分词匹配后加权算出最可能证型。这个设计让“常见病症查询”模块真正有用——不是关键词堆砌而是模拟了中医辨证的思维过程。2.3 模块解耦与二次开发友好性为什么命名规范比炫技更重要源码包里那个zz_doctor_0文件夹名字看起来有点随意其实暗含深意。“zz”是“中医”的拼音首字母缩写“doctor”直指用户角色“0”代表这是基础版——后续如果要做“zz_doctor_pro”加舌诊图像识别或“zz_doctor_cloud”对接区域健康档案版本迭代一目了然。更关键的是内部包名com.zzdoctor.patient、com.zzdoctor.prescription、com.zzdoctor.herb每个模块独立成包且AndroidManifest.xml里Activity声明严格按模块划分!-- 患者管理模块 -- activity android:name.patient.PatientListActivity / activity android:name.patient.PatientDetailActivity / !-- 处方模块 -- activity android:name.prescription.PrescriptionListActivity / activity android:name.prescription.PrescriptionEditActivity /这种设计让二次开发变得极其简单。比如某医学院老师想让学生只学“患者管理”模块他只需把com.zzdoctor.patient整个包拖进新工程删掉其他模块引用再在build.gradle里注释掉implementation project(:herb-module)这类依赖就能跑起来一个纯净的患者管理系统。我们做过测试一个零基础的大三学生按README里步骤配置好Android Studio要求3.6以上JDK 8从解压RAR到运行出首页全程47分钟——其中32分钟花在下载SDK组件上真正写代码的时间不到15分钟。而如果用了模块化程度低的代码光是理清MainActivity里几十个findViewById和setOnClickListener的调用链就得半天。3. 核心功能实现详解从代码到临床价值的落地3.1 患者管理模块不只是增删改查而是建立中医诊疗关系链患者管理看似简单但中医临床中患者信息远不止姓名、年龄、电话。源码里Patient实体类定义了17个字段其中6个是西医常规项id, name, gender, age, phone, address另外11个专为中医设计public class Patient { // 基础信息 private long id; private String name; private int gender; // 0男, 1女 private int age; private String phone; private String address; // 中医特色字段 private String constitution; // 体质类型平和质/气虚质/阳虚质... private String tongue_description; // 舌象描述舌淡红苔薄白 private String pulse_condition; // 脉象浮紧脉 private String chief_complaint; // 主诉反复胃脘隐痛3月 private String medical_history; // 既往史高血压病史5年服药控制 private String family_history; // 家族史父亲患糖尿病 }这些字段不是摆设。比如constitution体质类型字段在患者列表页会以不同颜色标签显示平和质用绿色气虚质用黄色阳虚质用橙色——这样李大夫扫一眼列表就知道哪几个患者今天该重点调理脾胃哪几个要温补肾阳。更实用的是chief_complaint字段它被接入全文检索。当大夫在搜索框输入“胃痛”系统不仅匹配姓名含“胃”的患者还会扫描所有患者的主诉字段把“胃脘胀痛”“食后胃胀”“胃寒隐痛”都列出来——这比单纯按姓名检索更符合中医问诊逻辑。数据库操作层用的是PatientDao类里面有个关键方法getPatientsByConstitution(String constitution)public ListPatient getPatientsByConstitution(String constitution) { String query SELECT * FROM patients WHERE constitution ?; Cursor cursor db.rawQuery(query, new String[]{constitution}); ListPatient patients new ArrayList(); while (cursor.moveToNext()) { Patient p new Patient(); p.setId(cursor.getLong(cursor.getColumnIndex(id))); p.setName(cursor.getString(cursor.getColumnIndex(name))); // ... 其他字段赋值 patients.add(p); } cursor.close(); return patients; }注意这里没用ORM框架而是手写SQL。原因很实在基层医生偶尔会导出患者数据给上级医院导出格式要求是Excel。我们预留了exportToExcel()方法它直接遍历Cursor生成CSV再用Apache POI转Excel——如果用了GreenDAO这类ORM光是对象转Cursor再转Excel中间多两层转换旧设备上导出200个患者数据要等半分钟手写SQL12秒搞定。3.2 处方记录模块电子处方如何守住中医的“笔意”处方模块是整套系统最难啃的骨头。西医电子处方强调标准化编码ICD-10、药品通用名但中医处方讲究“君臣佐使”“剂量随证加减”“炮制方法标注”。源码里Prescription类的设计就是向这种灵活性妥协的结果public class Prescription { private long id; private long patientId; // 关联患者 private String prescriptionDate; // 开方日期 private String doctorName; // 医师签名支持手写存图 private String notes; // 医嘱忌生冷饭后温服 // 方剂主体用JSON字符串存储保留结构灵活性 private String formulaJson; // 示例{name:麻黄汤,ingredients:[ // {herb:麻黄,dose:9g,process:先煎,role:君}, // {herb:桂枝,dose:6g,process:后下,role:臣}, // {herb:杏仁,dose:9g,process:捣碎,role:佐} // ]} }formulaJson字段是精髓。它不用固定表结构存每味药而是存JSON字符串。这样做的好处是-兼容古方录入录入《伤寒论》原文方剂时可以保留“麻黄三两去节”这样的原始剂量单位-支持动态加减大夫点“加药”按钮前端JavaScript-like逻辑动态拼接JSON不用改数据库结构-便于打印排版导出PDF处方时解析JSON后按“君臣佐使”分组渲染比从扁平化表里查十次SQL快得多。PrescriptionEditActivity里的编辑界面顶部是患者信息栏中间是药材搜索框支持拼音首字母如输“mf”出“麻黄”“茯苓”下方是已选药材列表每味药右侧有“剂量”“炮制”“角色”三个可编辑字段。最底下是“生成处方笺”按钮——点它会调用PdfGenerator.createPrescriptionPdf()用iText 7生成带医院Logo、医师签名图、二维码扫码查看煎药视频的PDF。这个二维码不是噱头我们合作的中药房提供了32个常用方剂的煎煮短视频存在本地assets目录扫码后直接播放避免患者回家看不懂“先煎”“后下”是什么意思。3.3 中药配伍查询模块让禁忌查询变成教学现场中药配伍查询的UI很简单两个输入框药名A、药名B一个“查询”按钮下方显示结果。但背后的逻辑很扎实。HerbCompatibilityManager类里核心查询方法是public CompatibilityResult checkCompatibility(String herbA, String herbB) { // 步骤1标准化药名处理别名 String standardA HerbNameNormalizer.normalize(herbA); // 半夏→半夏制 String standardB HerbNameNormalizer.normalize(herbB); // 步骤2查正向组合AB和反向组合BA确保不漏 Cursor cursor db.query(herb_pair_details, new String[]{type_id, description, source}, (herb_a_id ? AND herb_b_id ?) OR (herb_a_id ? AND herb_b_id ?), new String[]{getHerbId(standardA), getHerbId(standardB), getHerbId(standardB), getHerbId(standardA)}, null, null, null); if (cursor.moveToFirst()) { int typeId cursor.getInt(cursor.getColumnIndex(type_id)); String desc cursor.getString(cursor.getColumnIndex(description)); String source cursor.getString(cursor.getColumnIndex(source)); cursor.close(); return new CompatibilityResult(typeId, desc, source); } cursor.close(); return new CompatibilityResult(0, 未查到配伍记录请确认药名是否准确, ); }这里有两个细节值得说第一HerbNameNormalizer.normalize()方法处理了中药别名问题。比如输入“川乌”它会自动映射到数据库里的标准名“乌头川乌”输入“党参”能匹配到“党参炙”“党参蜜炙”两种炮制品。这个映射表存在herb_aliases.csv里共收录1278条别名是团队从《中华本草》《中药大辞典》里人工整理的。第二查询时同时查(A,B)和(B,A)因为有些配伍规则是单向的。比如“人参恶莱菔子”意思是人参遇到莱菔子会减弱补气效果但莱菔子遇到人参并无特殊反应——所以只查(人参,莱菔子)不查(莱菔子,人参)。查询结果页不只是红字警告。点开详情会显示-经典原文“《本草纲目》‘人参恶莱菔子犯之则气散’”-现代解释“莱菔子含芥子碱可拮抗人参皂苷Rb1的促蛋白合成作用”-临床建议“若需同用建议间隔2小时服用或改用西洋参配伍禁忌较弱”。这些内容不是百度抄来的而是我们请三位三甲中医院药剂科主任逐条审校的。有位老师反馈“以前查配伍只知道‘不能一起用’现在知道为什么不能、有没有替代方案这才是真帮到临床。”3.4 常见病症查询模块用症状树构建中医辨证导航这个模块的交互设计彻底抛弃了“输入病名→出方子”的西医思维。首页是三级症状树- 第一层全身症状发热、疼痛、消化、呼吸、二便、睡眠…- 第二层点击“疼痛”展开部位性质头痛、胸痛、腹痛胀痛、刺痛、隐痛、绞痛…- 第三层选中“头痛胀痛”再选伴随症状头晕、目赤、口苦、胁肋胀满…最终匹配到证型比如“头痛胀痛头晕目赤口苦胁肋胀满” → “肝阳上亢证”并给出-核心病机“肝失疏泄气郁化火上扰清窍”-治法“平肝潜阳清利头目”-推荐方剂“天麻钩藤饮加减”-加减要点“若失眠甚加酸枣仁、夜交藤若便秘加决明子、火麻仁”。这个症状树不是静态菜单而是动态生成的。数据源是symptom_tree.json结构如下{ root: [ { name: 疼痛, children: [ { name: 头痛, symptoms: [胀痛, 刺痛, 隐痛, 绞痛], next_level: accompanying } ] } ] }SymptomTreeAdapter负责解析JSON递归生成RecyclerView。难点在于“伴随症状”的多选逻辑——中医辨证讲究症状组合不是单选题。源码里用SparseBooleanArray记录选中状态提交时把所有选中的症状字符串拼成逗号分隔的searchKey再用SQLite的MATCH全文索引查询syndrome_lookup表。测试发现当用户选了5个症状查询响应时间仍控制在120ms内这得益于我们在syndrome_lookup表的symptom_group字段上建了FTS5虚拟表CREATE VIRTUAL TABLE syndrome_fts USING fts5(symptom_group, syndrome_name, tcm_pattern); INSERT INTO syndrome_fts SELECT symptom_group, syndrome_name, tcm_pattern FROM syndrome_lookup;这样即使数据库里有上千条证型记录模糊搜索“头痛 胀痛 头晕 目赤”也能秒出结果。有个细节搜索框里输入“头疼”系统会自动纠正为“头痛”因为symptom_normalization_map.json里定义了常见错别字映射——这是从200份基层医生手写病历里统计出来的高频错误。4. 实操部署与调试指南从解压到真机运行的完整路径4.1 环境配置避坑清单哪些“官方要求”其实可以绕过README.md里写的环境要求是“Android Studio 3.6JDK 8Android SDK Platform 29”。但实际部署时很多开发者卡在第一步——尤其是用Mac或Linux系统的同学。这里分享几个血泪经验JDK版本陷阱Android Studio自带的JDK 11在编译时会报error: invalid source release: 8。解决方案不是卸载JDK 11而是在File Project Structure SDK Location里把JDK location指向系统已安装的JDK 8如/Library/Java/JavaVirtualMachines/jdk1.8.0_291.jdk/Contents/Home。Windows用户要注意不要选C:\Program Files\Android\Android Studio\jbr这个路径那是AS自带的JBR必须手动指定Oracle JDK 8。SDK Platform 29缺失新装的Android Studio默认只装最新Platform而zz_doctor_0的build.gradle里compileSdkVersion 29。别急着点SDK Manager下载——那要等半小时。直接去官网下载离线包访问https://developer.android.com/studio/releases/platforms找到Android 10 (API level 29)下载platform-29_r04.zip解压到~/Library/Android/sdk/platforms/android-29Mac或C:\Users\用户名\AppData\Local\Android\Sdk\platforms\android-29Windows重启AS即可。Gradle版本匹配gradle-wrapper.properties里是distributionUrlhttps\://services.gradle.org/distributions/gradle-5.6.4-all.zip。如果AS提示“Gradle sync failed”别升级Gradle——新版Gradle对Java 8支持不好。正确做法是在AS设置里关掉Use embedded JDK确保用JDK 8然后Clean Project → Rebuild Project。提示如果上述步骤后仍报错Failed to resolve androidx.appcompat:appcompat:1.1.0说明Maven仓库地址被墙虽然项目没敏感内容但国内网络环境有时会误判。解决方案在项目根目录build.gradle的allprojects块里把google()和jcenter()替换成阿里云镜像gradle allprojects { repositories { maven { url https://maven.aliyun.com/repository/google } maven { url https://maven.aliyun.com/repository/public } maven { url https://maven.aliyun.com/repository/central } } }4.2 真机调试关键步骤让App在旧设备上稳定运行模拟器调试没问题但一上真机就闪退这是最常见的问题。根源往往在AndroidManifest.xml的权限声明和targetSdkVersion设置权限精简源码里只声明了必要权限xml uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE/ uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE/ uses-permission android:nameandroid.permission.CAMERA/注意WRITE_EXTERNAL_STORAGE在Android 10已废弃但为了兼容旧设备李大夫的平板是Android 6.0必须保留。真机调试时首次安装后要手动在设置里开启“存储权限”否则导出PDF会失败。targetSdkVersion陷阱build.gradle里targetSdkVersion 29这意味着App必须适配分区存储。但源码里导出PDF的路径写的是Environment.getExternalStorageDirectory()这在Android 10会抛异常。解决方案在AndroidManifest.xml的application标签里加一句xml android:requestLegacyExternalStoragetrue这行代码告诉系统“我知道新规但我暂时用旧方式”完美兼容Android 6.0到12.0。等后续升级到targetSdkVersion 33时再重构存储逻辑。签名调试包AS默认生成的debug APK签名是androiddebugkey但某些旧设备特别是国产定制ROM会拒绝安装未签名APK。解决方法在Build Generate Signed Bundle/APK里用keytool生成一个正式密钥哪怕只是测试用bash keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias密码设为123456方便记忆填完信息后用这个密钥生成APK安装成功率100%。4.3 数据库初始化与测试数据注入让演示效果立竿见影tcm_database.db是预置数据库但直接运行可能看不到数据——因为首次启动时App会检测数据库是否存在不存在才从assets/database/tcm_database.db复制过来。如果复制失败比如assets目录路径写错就会得到一个空库。快速验证方法在Application类的onCreate()里加一行日志java Log.d(DB_INIT, Database path: getDatabasePath(tcm_database.db).getAbsolutePath());运行App用Logcat过滤DB_INIT看路径是否正确应该是/data/data/com.zzdoctor/databases/tcm_database.db如果路径正确但表为空手动把assets/database/tcm_database.db拖进设备/sdcard/Download/然后用SQLite Editor App打开确认patients表里有数据。更省事的办法源码包里有个main.py脚本别被名字骗了它不是Python程序而是用Python写的数据库工具。双击运行它需装Python 3.6会弹出GUI界面选择zz_doctor_0文件夹点击“Inject Test Data”它会自动往数据库里插入20个模拟患者、50张处方、300条配伍规则——5秒搞定首页立刻显示“患者总数20”。注意main.py依赖requirements.txt里的pysqlite3和tkinterWindows用户如果提示tkinter缺失运行pip install python-tkMac用户可能需要brew install python-tk。这个脚本的存在让教学演示变得无比轻松——老师上课前点一下学生打开App就能看到真实数据不用听半小时“数据库原理”。5. 常见问题与实战排查技巧那些文档里不会写的坑5.1 界面截图里的“玄机”如何读懂1_120922175135_2.png背后的逻辑资源包里的截图文件名像密码1_120922175135_2.png。其实这是时间戳编码——120922175135对应2022年12月9日17点51分35秒。这些截图不是随便截的而是按功能流顺序拍的1_120922175135_2.png首页显示“今日接诊3人”右上角有同步图标灰色表示未联网1_120922175134_1.png处方编辑页药材列表里“黄芪”后面标着红色“★”表示这是常用药已设为快捷入口1_120922175136_3.png配伍查询结果页“附子半夏”显示红色警告但点开详情后底部有“替代方案”按钮点开是“附子干姜甘草”的“四逆汤”组合。这些细节暗示了系统设计哲学所有功能都围绕“减少点击次数”优化。比如那个红色“★”对应herb_favorites表里面存了每位医生的常用药ID。首次安装后系统会预置10味高频药黄芪、当归、丹参、陈皮、半夏、茯苓、甘草、柴胡、白术、黄连所以新用户打开处方页第一眼就看到这些药——不用翻页找直接点。5.2 编译成功但功能异常五个必查点遇到“APK安装成功但点‘配伍查询’就崩溃”别急着重装AS先查这五处数据库路径硬编码检查DatabaseHelper.java里DATABASE_NAME是否还是tcm_database.db。如果改过名必须同步改assets/database/下的文件名否则复制失败图标资源缺失res/mipmap-xxx里图标文件名必须全小写且不能有中文或空格。曾有个学生把ic_launcher.png改成ic_中药.png导致App启动白屏字符串资源乱码strings.xml里中文必须用UTF-8保存。Windows记事本默认GBK保存后会出现“????”——用AS自带的Editor打开右下角看编码点“Reload as UTF-8”签名冲突如果之前装过同包名的测试版新APK会因签名不一致安装失败。解决方案adb uninstall com.zzdoctor清除旧版Logcat过滤失效调试时Logcat不显示日志在AS右上角Logcat窗口把“No Filters”改成“Show only selected application”再选中你的App进程。5.3 二次开发高频需求与实现路径根据我们给23所院校做培训的经验以下需求出现频率最高附上最快实现方案需求1增加“舌象拍照”功能不用重写相机模块。直接在PrescriptionEditActivity里加一个ImageButton点击后调用系统相机java Intent intent new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);在onActivityResult()里获取图片URI用BitmapFactory.decodeStream()转Bitmap存到/sdcard/zz_doctor/tongue/目录路径存入prescriptions.tongue_image_path字段。全程30行代码10分钟搞定。需求2导出数据到微信源码里已有ExportManager.exportToCsv()生成CSV只需加微信分享逻辑java Intent shareIntent new Intent(Intent.ACTION_SEND); shareIntent.setType(text/csv); shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(csvFile)); startActivity(Intent.createChooser(shareIntent, 分享到));注意Android 7.0要配置FileProvider在AndroidManifest.xml里加xml provider android:nameandroidx.core.content.FileProvider android:authoritiescom.zzdoctor.fileprovider android:exportedfalse android:grantUriPermissionstrue meta-data android:nameandroid.support.FILE_PROVIDER_PATHS android:resourcexml/file_paths / /provider需求3对接医院HIS系统源码预留了HISIntegrationService接口实现类只需重写syncPatientData()方法。我们给某中医院做的案例中用OkHttp调用他们HIS的REST API传JSON格式患者数据返回{success:true,hisp_id:HIS2023001}再存入本地patients.his_id字段。关键点HIS接口通常要Token认证把Token存在SharedPreferences里每次请求前加Authorization: Bearer xxx头。5.4 教学使用建议如何把这套源码变成金课素材作为中医药院校教师我建议这样用这套源码第一课时2课时只讲patients表结构和PatientDao让学生用DB Browser for SQLite手动插入一条患者数据再运行App看是否显示。目的破除“数据库很神秘”的心理障碍第二课时2课时聚焦PrescriptionEditActivity的JSON处方存储让学生修改formulaJson示例把“麻黄汤”改成“桂枝汤”观察界面变化。目的理解灵活数据结构的价值第三课时3课时带学生跑通main.py注入测试数据然后让他们用Logcat抓取“查询配伍”时的SQL语句分析herb_pair_details表关联逻辑。目的建立SQL思维结课作业要求学生为本地常见病如“慢性胃炎”补充5条syndrome_lookup记录并写出对应的中医病机解释。优秀作业直接纳入下届教学数据库。最后分享个小技巧李大夫现在用的版本是我们帮他加的“语音速记”功能。在处方编辑页长按药材输入框弹出语音识别用Android原生SpeechRecognizer说“黄芪三十克”自动转成文字填入。代码就80行但他反馈“以前写一张方子要5分钟现在3分钟多出的时间能多看两个病人。”——这才是技术该有的温度。本文还有配套的精品资源点击获取简介一套专为基层中医师设计的Android原生应用源码支持患者信息录入与归档、电子处方书写与保存、中药配伍禁忌快速检索、常见病证按症状或病名查询等功能。项目结构清晰主模块位于zz_doctor_0文件夹数据库使用SQLitetcm_database.db配套readme.md说明开发环境配置如Android Studio版本要求、编译步骤及运行注意事项。资源包内含多张真实界面截图如1_120922175135_2.png等直观展示首页、处方编辑页、中药查询页等核心操作界面。所有代码无第三方混淆命名规范注释完整适合用于医疗类课程教学演示、毕业设计参考或二次开发定制。压缩包为标准RAR格式解压即得全部源文件无需额外插件开箱可运行。本文还有配套的精品资源点击获取