产品名:Flow
目标平台:Android(优先),iOS(可选)
前端:React Native(你说的 “reactive native” 我这里按 React Native 理解)
后端:FastAPI(可选:仅当需要在线音乐列表/在线播放)
定位:“用音乐替代闹钟”的定时播放 + 基础音乐播放器
你想做一个能每天定时播放音乐的 App,达到“取代闹钟”的效果;同时借此完整实操一遍“从 0 到 APK”以及(可选)“前后端联动”开发流程。
- 用户可以设置每日定时播放(像闹钟一样可靠)。
- 音乐来源支持两种模式:
- 本地模式(单机 App):扫描手机本地音乐并播放。
- 在线模式(带后端):从服务器获取音乐列表并在线播放。
- 提供常见播放器能力:播放/暂停、上一首/下一首、进度条、列表、删除、拖动排序。
- 输出可安装的 Android APK(Debug/Release)。
- 不做复杂社交、评论、分享、推荐算法。
- 不做 DRM/付费音乐版权分发(仅支持用户自有/授权资源)。
- v0.1 不追求多设备同步与账号体系(后续可扩展)。
- 想用音乐唤醒自己、替代系统闹钟的人。
- 想要简单播放器 + 定时功能,不追求“重度音乐社区”。
- 每日 7:30 自动播放“起床歌单”,手机锁屏也能正常响起。
- 用户有一堆本地 MP3,想一键扫描导入并整理顺序。
- 用户有自己的服务器音乐库,点击“获取音乐”后展示列表并在线播放。
- 定时播放:按用户设置的时间点触发播放(每天/指定星期几)。
- 唤醒模式:触发后应尽量确保能发声(需要处理权限、后台限制、通知/前台服务)。
- 本地音乐:通过 Android MediaStore 或文件选择器读取的音频资源。
- 在线音乐:后端返回可播放 URL(如 MP3、AAC、HLS)。
- ✅ 本地扫描/导入音乐(至少能导入系统媒体库里的音频)
- ✅ 播放器:播放/暂停、上一首/下一首、进度条、当前播放信息
- ✅ 播放列表:展示、拖动排序、删除
- ✅ 定时播放:每日固定时间触发(至少 1 组定时)
- ✅ Android 打包:Debug APK + Release APK(带签名)
- 在线音乐:从服务器拉取列表、在线播放、切换音质(可选)
- 多组定时(例如工作日/周末不同)
- 逐渐增大音量(fade-in)、自动停止(例如播放 30 分钟后停止)
- 下载离线缓存、收藏/最近播放
- 账号体系 + 多端同步(后端升级)
- 更完整的播放器体验(歌词、均衡器等)
用户故事:
作为用户,我想从手机里找到音乐并导入到 Flow,这样我可以在 App 里直接播放和定时播放。
功能点:
- 扫描系统媒体库(推荐 Android MediaStore),列出可用音频:
- 字段:标题、艺术家、时长、文件大小(可选)、uri/path
- 支持“手动添加”:
- 通过系统文件选择器选取音频文件(Storage Access Framework)
- 将导入的音乐保存为“Flow 播放列表”本地数据(SQLite/AsyncStorage)。
验收标准:
- 首次打开可请求读取媒体权限并成功展示音乐。
- 至少能导入并播放 3 种常见格式(MP3/AAC/M4A 视设备支持)。
用户故事:
作为用户,我想点击“获取音乐”从服务器拿到音乐列表并在线播放。
功能点:
- App 端:
- 点击按钮请求后端
/api/tracks - 展示返回的音乐列表并可点击播放
- 点击按钮请求后端
- 服务端:
- 返回 track 列表(含可直接播放的 URL)
- 支持简单分页/搜索(可选)
验收标准:
- 点击获取后 3 秒内展示列表(局域网/普通服务器视情况)。
- 选择任意 track 可以播放且可以上一首/下一首切换。
- 播放/暂停
- 上一首/下一首
- Seek(拖动进度条)
- 显示:封面(可选)、标题、艺术家、已播放/总时长
- 列表展示(当前队列)
- 拖动排序(改变播放顺序)
- 从列表删除
- 播放模式(MVP 可先只做顺序播放;循环/随机可放 v0.2)
验收标准:
- 拖动排序后,下一首按新顺序播放。
- 删除当前播放曲目时,自动播放下一首或暂停(规则见 9.1)。
- 支持 1 组定时:
- 时间:HH:mm
- 重复:每日(每天触发)
- 动作:触发时开始播放指定播放列表(或继续播放队列第一首)
- 到点后:
- 唤起音频播放(必要时启用 Android 前台服务 + 通知)
- 开始播放(若无曲目则提示失败原因)
- 展示“正在唤醒”通知,点击通知进入播放页
- 需要考虑:
- 通知权限(Android 13+)
- 前台服务(Foreground Service)与媒体播放通知
- 设备省电策略可能导致定时不准:需要在设置页提示用户允许后台运行/忽略电池优化(可选但建议做提示)
验收标准:
- 屏幕锁定情况下,到点能播放(在常见机型/系统限制下尽量稳定)。
- App 杀进程后(被系统回收),仍能在多数情况下按时触发(取决于实现策略)。
- 首页 / 播放页
- 当前播放信息
- 播放/暂停、上一首/下一首
- 进度条
- “播放列表”入口
- 播放列表页
- 列表(拖动排序、左滑删除或按钮删除)
- “导入本地音乐”按钮
- “获取服务器音乐”按钮(在线模式)
- 定时设置页
- 开关:启用/禁用
- 时间选择器
- (v0.2)重复规则、播放时长、fade-in
- 设置/关于
- 后端地址(在线模式)
- 权限状态提示(通知、电池优化等)
- 版本号
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 本地生成 UUID 或服务端 ID |
| title | string | 标题 |
| artist | string | 艺术家(可空) |
| durationMs | number | 时长毫秒(可空) |
| sourceType | enum | local / remote |
| uri | string | 本地 content:// uri 或远程 URL |
| artworkUri | string? | 封面(可选) |
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | UUID |
| name | string | 默认 “Flow 列表” |
| trackIds | string[] | 按顺序存储 |
| 字段 | 类型 | 说明 |
|---|---|---|
| enabled | boolean | 是否启用 |
| timeHHmm | string | 例如 “07:30” |
| repeat | enum | MVP:daily |
| playlistId | string? | 不填则使用当前队列 |
GET /api/health- 返回:
{ "ok": true }
- 返回:
GET /api/tracks- 返回:
[{ id, title, artist, durationMs, url, artworkUrl? }]
- 返回:
- 方案 A(简单):服务器目录下存音频文件,后端扫描目录生成列表。
- 方案 B(规范):写入 SQLite/Postgres 的 tracks 表,支持搜索/标签。
- 可先不做鉴权(局域网/个人服务器)。
- 若公网提供,建议 v0.2 加简单 token 或 basic auth。
- 删除非当前播放曲目:从列表移除即可。
- 删除当前播放曲目:
- 若列表仍有下一首:自动播放下一首
- 否则:停止播放并显示“列表为空”
- 行为:弹通知提示 “Flow 定时触发失败:无曲目”,并记录日志(本地)。
- 网络错误:提示“网络不可用”,可重试。
- 403/404:提示“资源不可用”,自动跳到下一首(可选)。
- 播放:
react-native-track-player(常见选择) - 列表拖拽:
react-native-draggable-flatlist - 本地存储:
@react-native-async-storage/async-storage(MVP),或 SQLite(更稳) - 后台/定时:
- Android 定时较复杂:可选
react-native-alarm-manager/react-native-background-fetch/ 自写原生模块 +AlarmManager/WorkManager - 建议路线:MVP 先用 WorkManager/AlarmManager(原生)做可靠触发,再桥接到 RN 调起 TrackPlayer
- Android 定时较复杂:可选
备注:Android 对后台与定时限制较多,想“像闹钟一样”稳定,最终大概率需要 原生(Kotlin/Java)参与,RN 主要做 UI 与业务层。
- 提供曲目列表与静态文件服务(或反向代理到对象存储)。
- Nginx(可选)做静态文件分发更高效。
- Node.js + npm/yarn
- Java JDK(通常 17)
- Android Studio + Android SDK
- React Native CLI 环境
- 初始化 RN 项目
npx react-native run-android- 生成 Debug APK(通常在
android/app/build/outputs/apk/debug/)
- 生成 keystore(一次性,妥善保存)
- 在
android/gradle.properties或android/app/build.gradle配置 signingConfig - 执行
./gradlew assembleRelease - 输出路径:
android/app/build/outputs/apk/release/
- Release 需要正确的包名、版本号(versionCode/versionName)
- Android 13+ 通知权限可能影响“到点提示/播放通知”
- 后台/定时相关需要在 Manifest 配置权限与 Service
- 本地扫描是否能找到音乐
- 播放/暂停/切歌是否正常
- 进度条拖动是否正常
- 列表拖动排序是否生效
- 列表删除是否生效
- 定时到点是否触发播放(锁屏/后台/杀进程分别验证)
- Debug/Release APK 是否可安装运行
- 至少测试 2 个 Android 版本(例如 Android 10/13+)
- 至少 2 个品牌(小米/华为/三星/Pixel 等任意两种)
- Day 1-2:项目搭架子
- RN 工程跑通 + 一个播放页面 UI
- Day 3-4:本地音乐导入
- MediaStore 列表 -> 点击可播放
- Day 5:播放列表管理
- 拖动排序 + 删除
- Day 6-7:定时播放(最难但最核心)
- AlarmManager/WorkManager 触发 -> 前台服务 -> 播放
- Day 8:Release 打包
- keystore + assembleRelease
- Day 9+:FastAPI 在线列表(可选)
/api/tracks+ 静态资源分发 -> App 拉取并播放
- PRD(本文件)
- 前端 RN 项目(Git)
- 后端 FastAPI 项目(可选)
- Debug APK + Release APK
- 简单 README:如何运行/如何打包/如何部署后端
你可以随时把你卡住的东西直接丢给我,比如:
- “我定时触发不了,日志是 XXX”
- “Android 13 通知权限怎么处理”
- “WorkManager 和 AlarmManager 我该选哪个”
- “TrackPlayer 在后台播放没声音” 我会按 你当前进度 给你最短路径的下一步(并把坑点提前告诉你)。