当前位置:首页 > 行业动态 > 正文

安卓开发数据库存放音乐

数据库选择与设计

数据库类型 适用场景 音乐文件存储方式
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;
    // 其他字段省略...
}

文件存储与数据库关联流程

  1. 文件保存

    File musicDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
    File file = new File(musicDir, "song.mp3");
    FileOutputStream fos = new FileOutputStream(file);
    // 写入音频数据流...
  2. 元数据入库

    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);

注意事项

  1. 大文件处理:使用ContentResolveropenInputStream()进行流式读取
  2. 权限管理
    • Android 10+需使用MediaStoreAPI
    • 添加android:requestLegacyExternalStorage="true"兼容旧版
  3. 性能优化
    • file_path字段创建唯一索引
    • 使用异步任务处理文件IO操作
  4. 文件格式验证:通过MediaPlayer.setDataSource()测试文件有效性

相关问题解答

Q1:如何在Android 11+系统实现音乐文件访问?
A1:需使用MediaStoreAPI,示例代码:

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:主要原因包括:

  1. SQLite单表最大支持1GB,不适合存储大文件
  2. 数据库版本升级时二进制数据易损坏
  3. 文件系统缓存机制比数据库更高效
  4. 便于多平台共享(如通过文件管理器访问
0