获取MP3音乐数据两种方式

    |     2016年2月18日   |   Android UI界面   |     0 条评论   |    4675

自己写音乐播放器,第一步是拿到本地 MP3。可以递归扫 SD 卡,也可以查系统媒体库 MediaStore——后者自带歌名、专辑、歌手和时长。


一、遍历文件过滤 MP3

本地音乐在手机存储里。一种做法是遍历文件,按后缀过滤:

/**
 * 扫描 Sdcard(外部存储)下所有文件
 */
public void scanFileList(File parentFile) {
    File[] listFile = parentFile.listFiles();
    if (listFile != null) {
        for (int i = 0; i < listFile.length; i++) {
            File file = listFile[i];
            if (file.isDirectory()) {
                scanFileList(file);
            } else {
                if (file.getName().endsWith("mp3")) {
                    MusicBean music = new MusicBean();
                    String fileName = file.getName();
                    music.setMusicName(fileName.substring(0, fileName.length() - ".mp3".length()));
                    music.setMusicPath(file.getAbsolutePath());
                    mMusicList.add(music);
                }
            }
        }
    }
}

调用后把 MP3 加进 mMusicList。扫盘是耗时操作,必须放进线程;刷新 ListView 再丢回主线程:

new Thread(new Runnable() {
    @Override
    public void run() {
        scanFileList(Environment.getExternalStorageDirectory());
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mAdapter.setListData(mMusicList);
            }
        });
    }
}).start();

MP3 里不止音频数据,还有歌名、专辑、歌手、路径、时长。靠递归读这些字段,得按文件格式自己解析。


二、查 MediaStore 媒体库

Android 启动、拔插 SD 卡时会发扫描广播,扫描服务把结果写入媒体库。URI 是 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,直接 query 就能拿。

查指定目录:

Cursor cursor = getContentResolver().query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,
        MediaStore.Audio.Media.DATA + " like ?",
        new String[]{dirName + "%"},
        MediaStore.Audio.Media.DEFAULT_SORT_ORDER);

查全部:

Cursor cursor = getContentResolver().query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
        MediaStore.Audio.Media.DEFAULT_SORT_ORDER);

结果里不只有 MP3,要再过滤。常用字段:

  • 歌曲 ID:MediaStore.Audio.Media._ID
  • 名称:TITLE
  • 专辑:ALBUM
  • 歌手:ARTIST
  • 路径:DATA
  • 时长:DURATION
  • 大小:SIZE
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
    String isMusic = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.IS_MUSIC));
    if (isMusic != null && isMusic.equals("")) continue;

    String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
    String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
    if (isRepeat(title, artist)) continue;

    music = new Music();
    music.setId(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID)));
    music.setTitle(title);
    music.setArtist(artist);
    music.setUri(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));
    music.setLength(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)));
    music.setImage(getAlbumImage(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID))));
    Constances.mMediaLists.add(music);
}

isRepeat() 按歌名+歌手去重;getAlbumImage() 按 album_id 读封面路径:

private boolean isRepeat(String title, String artist) {
    for (Music music : Constances.mMediaLists) {
        if (title.equals(music.getTitle()) && artist.equals(music.getArtist())) {
            return true;
        }
    }
    return false;
}

private String getAlbumImage(int albumId) {
    String result = "";
    Cursor cursor = null;
    try {
        cursor = getContentResolver().query(
                Uri.parse("content://media/external/audio/albums/" + albumId),
                new String[]{"album_art"}, null, null, null);
        for (cursor.moveToFirst(); !cursor.isAfterLast(); ) {
            result = cursor.getString(0);
            break;
        }
    } catch (Exception e) {
    } finally {
        if (null != cursor) {
            cursor.close();
        }
    }
    return null == result ? null : result;
}

三、列表展示

Music music = (Music) getItem(position);
Bitmap icon = BitmapFactory.decodeFile(music.getImage());
holder.icon.setImageBitmap(icon == null
        ? BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher)
        : icon);
holder.title.setText(music.getTitle());
holder.artist.setText(music.getArtist());

mediastore1

方式 拿到什么 注意
扫文件 路径 + 文件名 必须进线程;ID3 要自己解析
MediaStore 标题、歌手、时长、封面 过滤非音乐、去重、关掉 Cursor

一句话总结:只要文件路径可以扫盘;要歌名、歌手、封面和时长,直接查 MediaStore,别自己解析 MP3 头。

转载请注明来源:获取MP3音乐数据两种方式
本文链接地址:https://ai.zhousir.top/?p=1255
回复 取消