上一篇
安卓开发数据库存放音乐
- 行业动态
- 2025-04-21
- 3
数据库选择与设计
数据库类型 | 适用场景 | 音乐文件存储方式 |
---|---|---|
SQLite | 轻量级本地存储 | 仅存储文件路径/URI |
Room | 结构化数据存储 | 配合外部存储使用 |
Realm | 高性能对象存储 | 同SQLite方案 |
推荐方案:使用Room框架管理元数据(歌名/歌手/路径),音乐文件存储在外部存储空间
文件存储位置方案
存储位置 | 优点 | 缺点 |
---|---|---|
内部存储 | 自动备份至云 | 空间有限,需申请权限 |
外部存储 | 大容量,无需申请权限 | Android 10+需适配分区存储 |
应用专属目录 | 安全隔离,无需权限 | 清理时可能被系统删除 |
MediaStore | 标准媒体库集成 | 需要处理ContentProvider |
推荐路径:Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).toString()
数据库表结构设计
CREATE TABLE music_metadata ( id INTEGER PRIMARY KEY AUTOINCREMENT,TEXT NOT NULL, artist TEXT, album TEXT, duration INTEGER, -毫秒数 file_path TEXT UNIQUE NOT NULL, added_date DATETIME DEFAULT CURRENT_TIMESTAMP );
Room实体类定义
@Entity(tableName = "music_metadata") public class Music { @PrimaryKey(autoGenerate = true) public int id; @ColumnInfo(name = "title") public String title; @ColumnInfo(name = "artist") public String artist; @ColumnInfo(name = "file_path") public String filePath; // 其他字段省略... }
文件存储与数据库关联流程
文件保存:
File musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC); File file = new File(musicDir, "song.mp3"); FileOutputStream fos = new FileOutputStream(file); // 写入音频数据流...
元数据入库:
Music music = new Music(); music.title = "Song Title"; music.artist = "Artist Name"; music.filePath = file.getAbsolutePath(); musicDao.insert(music);
音频播放实现
MediaMetadataRetriever retriever = MediaMetadataRetriever.create(); retriever.setDataSource(music.getFilePath()); String durationStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
注意事项
- 大文件处理:使用
ContentResolver
的openInputStream()
进行流式读取 - 权限管理:
- Android 10+需使用
MediaStore
API - 添加
android:requestLegacyExternalStorage="true"
兼容旧版
- Android 10+需使用
- 性能优化:
- 为
file_path
字段创建唯一索引 - 使用异步任务处理文件IO操作
- 为
- 文件格式验证:通过
MediaPlayer.setDataSource()
测试文件有效性
相关问题解答
Q1:如何在Android 11+系统实现音乐文件访问?
A1:需使用MediaStore
API,示例代码:
ContentValues values = new ContentValues(); values.put(MediaStore.Audio.Media.DISPLAY_NAME, "song.mp3"); values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg"); Uri uri = resolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
Q2:为什么推荐存储文件路径而非二进制数据?
A2:主要原因包括:
- SQLite单表最大支持1GB,不适合存储大文件
- 数据库版本升级时二进制数据易损坏
- 文件系统缓存机制比数据库更高效
- 便于多平台共享(如通过文件管理器访问