【问题标题】:List all music in MediaStore with the PATHs使用 PATH 列出 MediaStore 中的所有音乐
【发布时间】:2012-11-26 16:18:51
【问题描述】:

好的,所以我已经在这个项目上工作了几天,我大部分时间都在研究如何在列表视图或其他方式中列出设备上的所有音乐,我已经搜索了一些现在几天,这正在杀死我。我确实在一个文件夹中显示所有音乐的时候如此接近,但由于大多数人都会有诸如 artiest 和专辑之类的子文件夹,我需要一种方法来搜索 MP3 或音乐文件的子文件夹。

这是我目前收集的音乐:

package com.androidhive.musicplayer;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.HashMap;

import android.provider.MediaStore;

public class SongsManager {
// SDCard Path
final String MEDIA_PATH = new String(MediaStore.Audio.Media.getContentUri("external").toString());
private ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();

// Constructor
public SongsManager(){

}

/**
 * Function to read all mp3 files from sdcard
 * and store the details in ArrayList
 * */
public ArrayList<HashMap<String, String>> getPlayList(){
    File home = new File(MEDIA_PATH);

    if (home.listFiles(new FileExtensionFilter()).length > 0) {
        for (File file : home.listFiles(new FileExtensionFilter())) {
            HashMap<String, String> song = new HashMap<String, String>();
            song.put("songTitle", file.getName().substring(0, (file.getName().length() - 4)));
            song.put("songPath", file.getPath());

            // Adding each song to SongList
            songsList.add(song);
        }
    }
    // return songs list array
    return songsList;
}

/**
 * Class to filter files which are having .mp3 extension
 * */
class FileExtensionFilter implements FilenameFilter {
    public boolean accept(File dir, String name) {
        return (name.endsWith(".mp3") || name.endsWith(".MP3"));
    }
}

}

感谢任何可以提供帮助的人。 :)

【问题讨论】:

  • 为什么不从 MediaStore 获取该列表?
  • 虽然我已经尝试过媒体商店,但我该怎么做..

标签: java android media mediastore


【解决方案1】:

虽然这篇文章很旧,但对于像我这样的其他人来说,如果想用他们的文件路径创建一个音乐列表,我在这里添加了解决方案。 MediaStore.Audio.Media.DATA 列实际上包含媒体文件路径。您可以使用以下 sn -p 获取必要的信息:

ContentResolver cr = getActivity().getContentResolver();

Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
Cursor cur = cr.query(uri, null, selection, null, sortOrder);
int count = 0;

if(cur != null)
{
    count = cur.getCount();

    if(count > 0)
    {
        while(cur.moveToNext())
        {
            String data = cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.DATA));
            // Add code to get more column here

            // Save to your list here
        }

    }

    cur.close();
}

【讨论】:

  • @AshishSahu 你能解释一下你的评论吗?我已经读了好几遍了,不明白你想说什么:)
  • @amos-bordowitz 可能是在 Ashish 发表评论后更正了代码,现在评论似乎不合适:)
  • 光标在 android pie api 28 中返回 null
  • @Ibrahim Gharyali:不知道发生了什么变化。好久没用游标了。
【解决方案2】:

您可以使用this code列出所有音乐文件

//Some audio may be explicitly marked as not being music
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

String[] projection = {
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.ARTIST,
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.DATA,
        MediaStore.Audio.Media.DISPLAY_NAME,
        MediaStore.Audio.Media.DURATION
};

cursor = this.managedQuery(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        null,
        null);

private List<String> songs = new ArrayList<String>();
while(cursor.moveToNext()) {
        songs.add(cursor.getString(0) + "||" 
                    + cursor.getString(1) + "||" 
                    + cursor.getString(2) + "||"
                    + cursor.getString(3) + "||"
                    + cursor.getString(4) + "||" 
                    + cursor.getString(5));
}

我没有尝试过这段代码,但它似乎是正确的。你会走在正确的轨道上。

【讨论】:

  • 嗯,我已经尝试过你的代码,但我似乎无法让它工作,你能修改我的代码并告诉我它是如何完成的吗:) 我会自己做,虽然我只是想不明白它。
  • @MarvinLabs 你知道从媒体商店获取文件路径的可能方法吗??对于特定歌曲?
  • 出色的代码。我一直在寻找近 8 个小时的解决方案。谢谢。
  • ManagedQuery 顺便说一句已被弃用。请改用 cursor.query 方法。
  • 文件夹按语法创建时不起作用stackoverflow.com/questions/48934159/…
【解决方案3】:

我现在正在做同一个项目,并且已经解决了这个问题。

您将需要一个自定义类来存储您的歌曲数据:

package YOUR_PACKAGE;

public class Songs
{
    private long mSongID;
    private String mSongTitle;

    public Songs(long id, String title){
        mSongID = id;
        mSongTitle = title;
    }

    public long getSongID(){
        return mSongID;
    }

    public String getSongTitle(){
        return mSongTitle;
    }
}

然后您必须使用列表视图在活动中定义 ArrayList,您将使用数据填充它:

private ArrayList<Songs> arrayList;

在 onCreate 中:

arrayList = new ArrayList<Songs>();

然后你必须从你的设备中检索数据:

public void YOUR_METHOD_NAME(){
    ContentResolver contentResolver = getContentResolver();
    Uri songUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor songCursor = contentResolver.query(songUri, null, null, null, null);

    if(songCursor != null && songCursor.moveToFirst())
    {
        int songId = songCursor.getColumnIndex(MediaStore.Audio.Media._ID);
        int songTitle = songCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);

        do {
            long currentId = songCursor.getLong(songId);
            String currentTitle = songCursor.getString(songTitle);
            arrayList.add(new Songs(currentId, currentTitle, currentArtist));
        } while(songCursor.moveToNext());
    }
}

然后从onCreate调用这个方法:

YOUR_METHOD_NAME();

最后你必须创建自定义适配器类,在 onCreate 中定义这个适配器(在 ListView 的活动中),然后在你的 ListView 对象上设置这个适配器。

我看到它是 3 年前提出的,我认为问题已经解决了,但也许它对某人有用。谢谢。

【讨论】:

    【解决方案4】:

    这是一个简单的函数,它为您提供文件对象中的所有音频文件。

     public static List<File> getAllAudios(Context c) {
        List<File> files = new ArrayList<>();
        String[] projection = { MediaStore.Audio.AudioColumns.DATA ,MediaStore.Audio.Media.DISPLAY_NAME};
        Cursor cursor = c.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, null, null, null);
        try {
            cursor.moveToFirst();
            do{
                files.add((new File(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)))));
            }while(cursor.moveToNext());
    
            cursor.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return files;
    }
    

    【讨论】:

    • 光标在 android pie api 28 中返回 null
    • MediaStore.Audio.Media.DATA 已弃用,值为 0,因此更新的 API 会崩溃。
    • @RowlandMtetezi "MediaStore.Audio.Media.DATA 已弃用" 这是真的。 “有 0 值”这是不正确的。仅仅因为它已被弃用并不意味着它不能再使用了。
    • @HB 我确实用它运行了我自己的代码,所以我确切地知道我在说什么。这也取决于正在运行的 API。因此,对于不推荐使用的 API,这两种说法都是正确的。我就是这么说的
    • @RowlandMtetezi So both statements are true--has 0 value 不正确。我们仍然可以使用数据列来检索设备上文件的文件路径。一些原生库需要文件对象,这就是 Google 在 Android R 中重新引入文件路径访问的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-18
    • 2017-02-05
    • 1970-01-01
    相关资源
    最近更新 更多