Files
Cyrene-For-Android/devdocs/02-interaction-flow.md
T

238 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 02 — 交互流程与导航设计
> **核心原则**:间接启动(语音/手势)不进入全屏 APP,而是以悬浮覆盖层呈现
> **关联文档**[01-voice-assistant-system.md](01-voice-assistant-system.md)
---
## 1. 启动来源 → 界面模式 映射表
```
┌──────────────────────────────────────────────────────────┐
│ 启动来源 │
├───────────────────────┬──────────────────────────────────┤
│ 直接启动 (Explicit) │ 间接启动 (Implicit) │
├───────────────────────┼──────────────────────────────────┤
│ · 桌面图标 │ · 语音唤醒 ("昔涟") │
│ · 最近任务列表 │ · 长按 Home 键 │
│ · 通知栏点击 │ · 底部两角向内滑动 │
│ · Deep Link │ · 长按电源键 (配置后) │
│ │ · 耳机按键 (单击/长按) │
│ │ · 锁屏右滑助手 │
├───────────────────────┼──────────────────────────────────┤
│ ▼ │ ▼ │
│ 全屏 Activity │ VoiceInteractionSession │
│ (MainActivity) │ (全屏悬浮覆盖层) │
│ · 完整导航栏 │ · 无导航栏 │
│ · Tab 切换 │ · 仅对话卡片 │
│ · 设置/IoT 面板 │ · 半透明遮罩透出底层 │
│ · 压入返回栈 │ · 不压入返回栈 │
└───────────────────────┴──────────────────────────────────┘
```
## 2. 全屏 Activity 模式
### 2.1 导航结构
```
MainActivity
├── BottomNavigation
│ ├── Tab 1: 对话 (ChatScreen) ← 默认页
│ ├── Tab 2: IoT 面板 (IoTScreen)
│ └── Tab 3: 我的 (ProfileScreen)
├── TopAppBar
│ ├── 昔涟状态指示器 (在线/思考中/离线)
│ └── 快捷操作 (设置、通知)
└── 子页面 (通过 NavHost 导航)
├── SettingsScreen
├── MemoryScreen (记忆查看)
├── KnowledgeScreen (知识库)
├── AutomationScreen (自动化规则)
├── ReminderScreen (提醒列表)
└── LoginScreen
```
### 2.2 导航图 (NavGraph)
```
LoginScreen ──(登录成功)──► MainScreen (带 BottomNav)
┌────────────┼────────────┐
▼ ▼ ▼
ChatScreen IoTScreen ProfileScreen
│ │
▼ ▼
MemoryScreen SettingsScreen
KnowledgeScreen ├─ Account
AutomationScreen ├─ Appearance (主题)
ReminderScreen ├─ Voice (唤醒词/语音)
├─ IoT Config
└─ About
```
### 2.3 登录流程
```
APP 首次启动
→ 检查本地 Token
├─ 有效 → 直接进入 MainScreen
└─ 无效 → LoginScreen
├─ 输入 Gateway 地址 + 账号密码
├─ POST /api/v1/auth/login
├─ 保存 Token 到 DataStore
└─ 进入 MainScreen
```
## 3. 悬浮覆盖层模式 (VoiceInteractionSession)
### 3.1 视觉层级
```
┌──────────────────────────────────────┐
│ 底层 APP (半透明可见) │
│ ┌──────────────────────────────┐ │
│ │ 半透明黑色遮罩 (80% 不透明度) │ │
│ │ │ │
│ │ ┌──────────────────────┐ │ │
│ │ │ │ │ │
│ │ │ 对话卡片区域 │ │ │
│ │ │ (圆角顶部 28dp) │ │ │
│ │ │ │ │ │
│ │ │ · 昔涟状态条 │ │ │
│ │ │ · 对话消息流 │ │ │
│ │ │ · 文本输入框 │ │ │
│ │ │ · 语音输入按钮 │ │ │
│ │ │ │ │ │
│ │ └──────────────────────┘ │ │
│ │ │ │
│ └──────────────────────────────┘ │
└──────────────────────────────────────┘
```
### 3.2 覆盖层生命周期
```
Trigger (唤醒词/手势/按键)
VoiceInteractionSession.onCreateContentView()
onShow() → 设置窗口属性 → 播放出现动画(底部滑入)
OverlayScreen Compose 渲染
├→ 用户说话 → STT → 显示识别文本 → 发送到 AI-Core
│ │
│ ▼
│ SSE 流式响应
│ │
├← TTS 语音播放 ←── 流式合成 ←────────────┘
├→ 用户打字输入 → WebSocket 发送 → 显示回复气泡
对话结束
├→ 用户主动关闭 (说"再见"/点击遮罩/下滑)
└→ 超时自动关闭 (静默 10 秒)
onHide() → 播放消失动画(底部滑出)
finish() → 返回触发前界面
```
### 3.3 覆盖层状态机
```
┌──────────┐
│ IDLE │ (覆盖层不可见)
└────┬─────┘
│ 触发
┌──────────┐
│LISTENING │ (等待语音输入,波形动画)
└────┬─────┘
│ 检测到语音 / 用户开始打字
┌──────────┐
│PROCESSING│ (STT 识别中 / LLM 思考中)
└────┬─────┘
│ 收到回复
┌──────────┐
│SPEAKING │ (TTS 播放中)
└────┬─────┘
│ 播放完毕,等待下一轮
┌──────────┐
│ WAITING │ (等待用户继续或关闭)
└────┬─────┘
┌───────┼───────┐
│ │
用户继续说话 10s 静默
│ │
▼ ▼
LISTENING IDLE
(覆盖层关闭)
```
### 3.4 与全屏 Activity 的切换
```
悬浮窗中用户点击 "打开完整 APP"
→ finish() 关闭悬浮窗
→ startActivity(MainActivity)
→ 用户在全屏模式下继续操作
全屏 APP 中用户按 Home 返回桌面
→ onStop() → 进入后台
→ WebSocket 保持连接
→ 推送/FCM 通知到达时,点击通知 → 恢复 MainActivity
```
## 4. 锁屏交互
### 4.1 锁屏唤醒
```
设备锁屏 + 息屏
├→ 说出唤醒词 "昔涟"
│ └→ onLaunchVoiceAssistFromKeyguard()
│ └→ 简化版覆盖层 (仅对话,无 IoT / 敏感操作)
└→ 长按电源键
└→ 同理
```
### 4.2 锁屏安全策略
| 操作 | 锁屏状态 | 行为 |
|------|---------|------|
| 查询天气/时间 | 允许 | 直接回复 |
| 简单闲聊 | 允许 | 直接回复 |
| IoT 查询(状态) | 允许 | 回复设备状态 |
| IoT 控制(开关) | **禁止** | 提示"请先解锁设备" |
| 查看记忆 | **禁止** | 提示"请先解锁设备" |
| 修改设置 | **禁止** | 提示"请先解锁设备" |
| 宿主命令 | **禁止** | 提示"请先解锁设备" |
## 5. 多窗口与分屏
- **分屏模式**:悬浮窗模式下不支持(本身已是覆盖层);全屏 Activity 支持分屏
- **画中画**:语音通话场景支持画中画(PIP),显示昔涟头像 + 波形动画
## 6. 手势交互
| 手势 | 悬浮窗模式 | 全屏 Activity |
|------|-----------|---------------|
| 下滑覆盖层 | 关闭悬浮窗 | — |
| 点击遮罩区域 | 关闭悬浮窗 | — |
| 长按消息 | 复制/分享菜单 | 复制/分享/删除 |
| 左滑消息 | — | 查看消息详情/时间戳 |
| 双击昔涟头像 | 切换输入模式(语音↔文字) | 同左 |