java - 在ListView中显示外部SD卡中的音乐文件列表

标签 java android listview audio-player

我想在我的应用程序中显示 SD 卡中可用的音乐文件列表。这是java代码。 代码工作正常,没有任何错误,但没有显示 MP3 文件,而是使用手机内存中的文件夹名称填充 ListView。

MainActivity.java

final String MEDIA_PATH = Environment.getExternalStorageDirectory().getAbsolutePath();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        ListView listsong =(ListView)findViewById(R.id.songslistView);

        ArrayList<String> mp3list = new ArrayList<String>();
        mp3list=mp3select();
        Toast.makeText(this, "mp3files" + mp3list,                Toast.LENGTH_LONG).show();

        ArrayAdapter<String> listAdapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,mp3list);
        listsong.setAdapter(listAdapter);

    }

    public ArrayList<String> mp3select(){
        File home = new File(MEDIA_PATH);
        ArrayList<String> list = new ArrayList<String>();
        //if (home.isDirectory())

        if (home.listFiles(new AudioFileFilter()).length > 0)
        {
            for (File file : home.listFiles(new AudioFileFilter()))
            {
                list.add(file.getName());
            }
        }
        return list;
    }

AudioFileFilter.java

public class AudioFileFilter implements FileFilter {

    protected static final String TAG = "AudioFileFilter";
    /**
     * allows Directories
     */
    private final boolean allowDirectories;

    public AudioFileFilter( boolean allowDirectories) {
        this.allowDirectories = allowDirectories;
    }

    public AudioFileFilter() {
        this(true);
    }

    @Override
    public boolean accept(File f) {
        if ( f.isHidden() || !f.canRead() ) {
            return false;
        }

        if ( f.isDirectory() ) {
            return allowDirectories;
        }
        String ext = getFileExtension(f);
        if ( ext == null) return false;
        try {
            if ( SupportedFileFormat.valueOf(ext.toUpperCase()) != null ) {
                return true;
            }
        } catch(IllegalArgumentException e) {
            //Not known enum value
            return false;
        }
        return false;
    }

    public String getFileExtension( File f ) {
        int i = f.getName().lastIndexOf('.');
        if (i > 0) {
            return f.getName().substring(i+1);
        } else
            return null;
    }

    /**
     * Files formats currently supported by Library
     */
    public enum SupportedFileFormat
    {
        _3GP("3gp"),
        MP4("mp4"),
        M4A("m4a"),
        AAC("aac"),
        TS("ts"),
        FLAC("flac"),
        MP3("mp3"),
        MID("mid"),
        XMF("xmf"),
        MXMF("mxmf"),
        RTTTL("rtttl"),
        RTX("rtx"),
        OTA("ota"),
        IMY("imy"),
        OGG("ogg"),
        MKV("mkv"),
        WAV("wav");

        private String filesuffix;

        SupportedFileFormat( String filesuffix ) {
            this.filesuffix = filesuffix;
        }

        public String getFilesuffix() {
            return filesuffix;
        }
    }

}

我已经解决了一些与该主题相关的问题。我无法识别问题所在。任何帮助表示赞赏。提前致谢。

最佳答案

您不会在目录中递归,相反,如果您已将allowDirectories传递给AudioFilter,那么您只是显示目录名称,因为您传递了一个默认为true的无参数构造函数。您想要执行的操作是扫描目录以查找与过滤器匹配的文件,当您找到子目录时,您希望将其添加到要扫描的目录列表中。您可以通过多种方式做到这一点。一种方法是递归。当您找到一个目录时,您可以使用该目录作为输入参数来调用相同的函数。另一种方法是您可以保留要扫描的目录列表,每次找到目录时,将其附加到列表中。扫描完目录中的文件后,从目录列表中弹出一个目录,然后继续,直到没有要扫描的目录为止。

这是递归方式的想法:

 private FileFilter mFileFilter;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    mFileFilter = new AudioFilter();

    ListView listsong =(ListView)findViewById(R.id.songslistView);

    ArrayList<String> mp3list = new ArrayList<String>();
    ArrayList<File> fileList = new ArrayList<File>();
    File home = new File(MEDIA_PATH);
    mp3select(home, fileList);
    //now you need to map your ArrayList<File> to ArrayList<String>.  Personally I would use a different kind of adapter and just return the name of the file while keeping the entire file reference


    ArrayAdapter<String> listAdapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,mp3list);
    listsong.setAdapter(listAdapter);

}

public void mp3select(File dir, ArrayList<File> fileList){  
    if (!home.isDirectory()) {
        return;
    }
    for (File file : home.listFiles(mAudioFilter))
    {
        if (file.isDirectory()) {
           mp3List(file, fileList);
        } else {
           fileList.add(file);
        }
    }
}

关于java - 在ListView中显示外部SD卡中的音乐文件列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33056345/

相关文章:

java - 来自 null 变量的 NullPointerException 错误。当 ListView 变空时

java - hibernate 和 jpa 怪异;意外的懒惰获取

java - -fx-background-radius 似乎无法正确使用四个值

Android源码编译

android - 发布适用于 Android 9 (Android API 28) 的 Cordova 应用程序出现互联网连接错误

android - ListFragment 不显示当前时间的变化

java - IntelliJ idea 图形用户界面设计器 + maven

java - 自动增量不适用于 ID

android - 如何从 Android Marshmallow 中的图库获取图像?

android - 在 ScrollView/WebView/ListView 中扩展滚动区域