鸿蒙app 急救知识库(症状自检/紧急联系人设置)【华为云根技术】
【摘要】 引言突发疾病或意外时,快速获取急救知识与联系紧急联系人至关重要。鸿蒙系统的分布式能力与实时响应特性,为急救知识库App提供了高效、可靠的开发基础,支持症状自检引导与紧急联系人快速触达,助力用户在危急时刻争取黄金救援时间。技术背景鸿蒙框架:基于Stage模型,@Entry/@Component构建UI,Ability管理生命周期,支持后台任务与通知推送。数据管理:急救知识以JSON文件预置,P...
引言
技术背景
-
鸿蒙框架:基于Stage模型, @Entry/@Component构建UI,Ability管理生命周期,支持后台任务与通知推送。 -
数据管理:急救知识以JSON文件预置, Preferences存储紧急联系人,关系型数据库缓存用户搜索记录。 -
交互能力:通过 弹窗展示自检流程,电话拨打接口实现一键呼叫,语音播报增强盲操作友好性。
应用使用场景
-
日常学习:用户浏览常见急症(如中暑、烫伤)处理步骤,提前储备知识。 -
症状自检:出现不适时,按引导回答问题(如“是否发热?”“有无呕吐?”),获取疑似病症及急救建议。 -
紧急求助:一键触发预设联系人呼叫,或快速拨打120并发送位置信息。
核心特性
-
智能症状自检:基于决策树算法,通过问答逐步缩小病症范围。 -
紧急联系人管理:支持增删改查,一键拨号与短信通知。 -
离线可用:急救知识本地存储,无网络时仍可访问。 -
多模态交互:图文指引+语音播报,适配不同用户习惯。
原理流程图与原理解释
流程图
graph TD
A[用户打开App] --> B[首页:知识库/自检/联系人]
B --> C[症状自检:选择部位/输入症状]
C --> D[决策树问答引导]
D --> E[输出疑似病症与急救步骤]
B --> F[紧急联系人:设置/呼叫]
F --> G[调用电话API拨打/发短信]
原理解释
-
症状自检:预定义决策树(如“头痛”分支包含“伴随发热→感冒/脑炎”“伴呕吐→颅内压增高”),用户每回答一个问题,系统跳转至对应子节点,直至匹配病症。 -
联系人管理:通过 Preferences存储联系人姓名与电话(键值对:contact_${index}→{"name":"张三","phone":"138xxx"}),调用@ohos.telephony.call发起呼叫。
环境准备
-
开发工具:DevEco Studio 4.0+ -
SDK版本:API 9+(支持电话、弹窗、文件读取) -
权限配置:在 module.json5中声明权限:"requestPermissions": [ { "name": "ohos.permission.PLACE_CALL" }, { "name": "ohos.permission.SEND_MESSAGES" }, { "name": "ohos.permission.READ_MEDIA" } // 读取本地知识库文件 ]
代码实现(完整示例)
1. 数据结构定义(Model/SymptomTree.ts)
// 决策树节点
export interface TreeNode {
question?: string; // 问题(如“是否发热?”)
options?: { text: string; nextNode: string }[]; // 选项与下一节点ID
disease?: string; // 最终病症(叶子节点)
advice?: string; // 急救建议
}
// 急救知识库(预置JSON转换)
export const symptomTree: Record<string, TreeNode> = {
root: {
question: "请选择不适部位",
options: [
{ text: "头部", nextNode: "head" },
{ text: "躯干", nextNode: "trunk" }
]
},
head: {
question: "是否头痛?",
options: [
{ text: "是", nextNode: "headache" },
{ text: "否", nextNode: "head_other" }
]
},
headache: {
question: "是否伴随发热?",
options: [
{ text: "是", nextNode: "cold" },
{ text: "否", nextNode: "migraine" }
]
},
cold: {
disease: "普通感冒",
advice: "1. 休息保暖;2. 温水擦浴降温;3. 体温>38.5℃可服退烧药。"
},
migraine: {
disease: "偏头痛",
advice: "1. 安静避光环境休息;2. 冷敷额头;3. 严重时就医。"
}
};
2. 紧急联系人管理(ViewModel/ContactManager.ts)
import preferences from '@ohos.data.preferences';
export class ContactManager {
private pref: preferences.Preferences | null = null;
async init(context: Context) {
this.pref = await preferences.getPreferences(context, 'contacts');
}
// 保存联系人(最多5个)
async saveContact(index: number, name: string, phone: string): Promise<boolean> {
if (!this.pref || index < 0 || index > 4) return false;
try {
await this.pref.put(`contact_${index}`, JSON.stringify({ name, phone }));
await this.pref.flush();
return true;
} catch (err) {
console.error(`Save contact failed: ${err}`);
return false;
}
}
// 获取所有联系人
async getContacts(): Promise<Array<{ name: string; phone: string }>> {
if (!this.pref) return [];
const contacts: Array<{ name: string; phone: string }> = [];
for (let i = 0; i < 5; i++) {
const data = await this.pref.get(`contact_${i}`, '{}');
const contact = JSON.parse(data as string);
if (contact.name) contacts.push(contact);
}
return contacts;
}
// 删除联系人
async deleteContact(index: number): Promise<boolean> {
if (!this.pref) return false;
await this.pref.delete(`contact_${index}`);
await this.pref.flush();
return true;
}
}
3. UI界面(pages/Index.ets)
import { symptomTree } from '../Model/SymptomTree';
import { ContactManager } from '../ViewModel/ContactManager';
import call from '@ohos.telephony.call';
@Entry
@Component
struct FirstAidPage {
@State currentNodeId: string = 'root'; // 当前决策树节点ID
@State selfCheckStep: string = ''; // 当前问题/结果
@State selfCheckOptions: { text: string; nextNode: string }[] = [];
@State result: { disease?: string; advice?: string } = {};
@State contacts: Array<{ name: string; phone: string }> = [];
@State showAddDialog: boolean = false;
@State inputName: string = '';
@State inputPhone: string = '';
private contactManager: ContactManager = new ContactManager();
aboutToAppear() {
this.loadSelfCheckNode('root');
this.loadContacts();
}
loadSelfCheckNode(nodeId: string) {
const node = symptomTree[nodeId];
if (node.disease) {
this.result = { disease: node.disease, advice: node.advice };
this.selfCheckStep = '';
this.selfCheckOptions = [];
} else {
this.selfCheckStep = node.question!;
this.selfCheckOptions = node.options!;
this.result = {};
}
}
async loadContacts() {
await this.contactManager.init(getContext());
this.contacts = await this.contactManager.getContacts();
}
build() {
Column({ space: 20 }) {
// 标题
Text("急救知识库").fontSize(24).fontWeight(FontWeight.Bold).margin(16);
// 标签页
Tabs({ barPosition: BarPosition.Start }) {
// 症状自检
TabContent() {
Column({ space: 15 }) {
if (this.result.disease) {
Text(`疑似病症:${this.result.disease}`).fontSize(18).fontColor(Color.Red);
Text(this.result.advice!).fontSize(16).padding(10).backgroundColor('#F5F5F5');
Button("重新自检").onClick(() => this.loadSelfCheckNode('root'));
} else {
Text(this.selfCheckStep).fontSize(18);
ForEach(this.selfCheckOptions, (option) => {
Button(option.text)
.width('80%')
.onClick(() => this.loadSelfCheckNode(option.nextNode));
})
}
}
}.tabBar("症状自检")
// 紧急联系人
TabContent() {
Column({ space: 10 }) {
List() {
ForEach(this.contacts, (item, index) => {
ListItem() {
Row() {
Column() {
Text(item.name).fontSize(16);
Text(item.phone).fontSize(14).fontColor(Color.Gray);
}.alignItems(HorizontalAlign.Start).layoutWeight(1)
Button("呼叫").onClick(() => call.makeCall(item.phone));
}.width('100%').padding(10)
}
})
}.width('100%').height(300)
Button("添加联系人").onClick(() => this.showAddDialog = true);
}
}.tabBar("紧急联系人")
}.width('100%').height('85%')
}
.width('100%').height('100%')
.bindSheet(this.showAddDialog, this.buildAddDialog(), { height: 300 })
}
@Builder buildAddDialog() {
Column({ space: 15 }) {
Text("添加联系人").fontSize(20).fontWeight(FontWeight.Bold);
TextInput({ placeholder: "姓名" }).onChange(val => this.inputName = val);
TextInput({ placeholder: "电话" }).type(InputType.PhoneNumber).onChange(val => this.inputPhone = val);
Row() {
Button("取消").onClick(() => this.showAddDialog = false);
Button("保存").onClick(async () => {
if (this.inputName && this.inputPhone) {
const index = this.contacts.length;
await this.contactManager.saveContact(index, this.inputName, this.inputPhone);
this.loadContacts();
this.showAddDialog = false;
this.inputName = '';
this.inputPhone = '';
}
});
}.justifyContent(FlexAlign.SpaceAround)
}.padding(20)
}
}
运行结果与测试步骤
运行结果
-
症状自检:从“选择部位”开始,依次回答问题,最终显示病症与急救建议(如“普通感冒”及处理步骤)。 -
紧急联系人:列表展示已保存联系人,点击“呼叫”直接拨号,点击“添加联系人”弹出输入框完成新增。
测试步骤
-
环境配置:创建鸿蒙工程,添加权限与代码文件,导入 symptomTree数据与ContactManager。 -
模拟器运行:使用API 9+模拟器,运行App,验证首页标签切换正常。 -
自检流程:依次点击“头部→是→是”,确认显示“普通感冒”及建议。 -
联系人操作:添加联系人“李四 139xxxx1234”,验证列表中显示并可呼叫。
部署场景
-
个人手机:作为独立App安装,适合日常携带与紧急使用。 -
社区终端:部署于社区服务中心大屏,居民可通过触控操作学习与求助。 -
车载系统:集成至鸿蒙车机,驾驶途中突发不适时快速呼救。
疑难解答
-
决策树跳转错误:检查 symptomTree中nextNode字段是否与节点ID一致。 -
呼叫失败:确认已申请 PLACE_CALL权限,且模拟器/真机开启电话功能。 -
联系人保存无效:验证 Preferences初始化是否成功(aboutToAppear中调用init)。
未来展望与技术趋势与挑战
未来展望
-
AI辅助诊断:接入大模型分析症状描述文本,提升自检准确率。 -
位置联动:呼叫120时自动发送实时位置至急救中心。 -
多语言支持:适配方言与外语,覆盖更广泛人群。
技术挑战
-
复杂病症覆盖:决策树难以穷举所有病症,需结合知识图谱扩展。 -
低网速优化:离线知识库体积较大时,需压缩存储与增量更新。
总结
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)