一款专为老年人设计的极简通讯 App — 照片拨号、一键紧急呼救、中英双语。 A minimalist communication app designed for seniors — photo-based dialing, one-touch SOS, bilingual (zh/en).
安心连(AnXin Link)解决老年人使用智能手机的三大痛点:
| 痛点 | 解决方案 |
|---|---|
| 操作复杂、找不到联系人 | 大头像照片网格,点一下即拨号 |
| 紧急情况反应慢 | 常驻红色 SOS 大按钮,长按 3 秒自动拨打紧急联系人 |
| 字太小看不清 | 可调字体、高对比度、Material 3 无障碍设计 |
目标用户:60 岁以上老年人(主要)/ 协助父母配置的子女(次要)
┌─────────────────────────────┐ HTTP/REST ┌──────────────────────┐
│ Flutter 前端 (iOS/Android/Web) │ ◄──────────────► │ FastAPI 后端 │
│ Riverpod · go_router │ │ SQLite (aiosqlite) │
│ sqflite (本地离线缓存) │ │ SQLAlchemy ORM │
└─────────────────────────────┘ └──────────────────────┘
| 层 | 技术 |
|---|---|
| 前端框架 | Flutter 3.x (Dart) |
| 状态管理 | Riverpod 2.x (AsyncNotifier) |
| 路由 | go_router |
| 本地数据库 | sqflite |
| HTTP 客户端 | Dio |
| 本地化 | flutter_localizations + intl (zh / en) |
| 拨号 / 短信 | url_launcher (tel:, sms:) |
| 图片选择 | image_picker |
| 权限管理 | permission_handler |
| 后端框架 | Python 3.11+, FastAPI |
| 后端数据库 | SQLite + aiosqlite + SQLAlchemy async |
| Schema 校验 | Pydantic v2 |
anxin-link/
├── frontend/ # Flutter 项目
│ ├── pubspec.yaml
│ ├── l10n.yaml
│ ├── lib/
│ │ ├── main.dart # 入口 + ProviderScope
│ │ ├── app.dart # MaterialApp.router + 路由 + 语言
│ │ ├── l10n/
│ │ │ ├── app_en.arb # 英文本地化字符串
│ │ │ └── app_zh.arb # 中文本地化字符串
│ │ ├── models/
│ │ │ ├── contact.dart
│ │ │ └── app_settings.dart
│ │ ├── providers/
│ │ │ ├── contacts_provider.dart
│ │ │ ├── settings_provider.dart
│ │ │ └── emergency_provider.dart
│ │ ├── screens/
│ │ │ ├── home_screen.dart # 照片网格 + SOS
│ │ │ ├── contacts_screen.dart # 联系人列表(滑动删除)
│ │ │ ├── add_contact_screen.dart # 添加 / 编辑联系人
│ │ │ ├── settings_screen.dart # 设置(语言 / 绑定码 / 字体)
│ │ │ └── emergency_overlay.dart # 全屏红色倒计时覆盖层
│ │ ├── widgets/
│ │ │ ├── contact_card.dart
│ │ │ ├── sos_button.dart
│ │ │ └── voice_dial_button.dart
│ │ └── services/
│ │ ├── api_service.dart # Dio → FastAPI 后端
│ │ ├── local_db_service.dart # sqflite 本地存储
│ │ └── call_service.dart # tel: / sms: 拨号
│ ├── android/app/src/main/
│ │ └── AndroidManifest.xml # 电话 / 短信 / 位置 / 相机权限
│ ├── ios/Runner/
│ │ └── Info.plist # iOS 权限描述
│ └── web/
│ ├── index.html
│ └── manifest.json
│
├── backend/ # FastAPI 项目
│ ├── requirements.txt
│ ├── main.py # FastAPI app + CORS + lifespan
│ ├── database.py # aiosqlite 连接池 + init_db
│ ├── models.py # SQLAlchemy ORM: Contact, Setting, BindingCode
│ ├── schemas.py # Pydantic v2 请求 / 响应 Schema
│ └── routers/
│ ├── contacts.py # CRUD /api/contacts
│ ├── settings.py # GET/PUT /api/settings
│ ├── binding.py # 亲子绑定码
│ └── emergency.py # 紧急通知
│
├── design/ # UI 设计稿 / 截图
└── prd/ # 产品需求文档
环境要求:Python 3.11+
cd backend
# 安装依赖
pip install -r requirements.txt
# 启动开发服务器
uvicorn main:app --reload服务启动后访问:
- Swagger UI:http://localhost:8000/docs
- ReDoc:http://localhost:8000/redoc
- 健康检查:http://localhost:8000/health
数据库文件自动创建于 backend/anxin_link.db(SQLite)。
环境要求:Flutter 3.x,Dart 3.3+
cd frontend
# 安装依赖
flutter pub get
# 生成本地化文件
flutter gen-l10n
# 运行(选择目标平台)
flutter run # 连接设备 / 模拟器
flutter run -d chrome # Web
flutter run -d ios # iOS 模拟器
flutter run -d android # Android 模拟器注意:后端默认监听
http://localhost:8000,前端lib/services/api_service.dart中的_baseUrl可按需修改。
在 android/app/build.gradle 中确认 minSdkVersion >= 21,然后在设备上授予以下权限:电话、短信、位置、相机。
Xcode 中配置 Bundle ID 与 Signing,所有权限描述已写入 ios/Runner/Info.plist。
| Method | Endpoint | 功能 |
|---|---|---|
GET |
/api/contacts |
获取所有联系人 |
POST |
/api/contacts |
新增联系人 |
PUT |
/api/contacts/{id} |
更新联系人 |
DELETE |
/api/contacts/{id} |
删除联系人 |
GET |
/api/settings |
获取应用设置 |
PUT |
/api/settings |
更新设置 |
POST |
/api/binding/generate |
生成亲子绑定码(8位) |
POST |
/api/binding/pair |
使用绑定码配对设备 |
POST |
/api/emergency/notify |
紧急通知(位置 + 联系人列表) |
GET |
/health |
健康检查 |
完整请求 / 响应格式见 /docs(Swagger)。
- 2×2 至 3×3 自适应照片联系人网格(大圆角卡片)
- 点击联系人卡片 → 直接拨号
- 长按卡片 → 进入编辑
- 顶部语音拨号按钮(麦克风图标)
- 底部常驻红色圆形 SOS 按钮
- 长按 SOS 触发全屏红色覆盖层
- 圆形进度条 3 秒倒计时
- 倒计时内可按"取消"终止
- 倒计时结束后:
- 向后端
POST /api/emergency/notify推送位置信息 - 依次拨打所有标记为"紧急联系人"的号码
- 向后端
- 大头像 + 大字体列表
- 右滑删除(二次确认)
- 长按 → 编辑
- 支持拍照 / 相册选头像
- 字体大小滑块(12–32px)
- 语音播报 / 自动接听开关
- 语言切换(中文 / English)— 热切换,无需重启
- 绑定码生成 / 配对(子女远程协助模式)
用户操作 → Riverpod Provider
→ LocalDbService (sqflite, 离线可用)
→ ApiService (Dio, 后端同步,失败不阻塞)
设计稿见 design/ 目录。
| screen1 | screen2 |
|---|---|
MIT License