【问题标题】:Android list music by folders and play themAndroid 按文件夹列出音乐并播放
【发布时间】:2012-06-09 07:25:45
【问题描述】:

我正在开发已经上市的安卓音乐播放器。 用户要求添加一个文件夹视图来列出他们智能手机中所有包含音乐的文件夹,我想开发它。

MediaStore 已经知道要遵循的正确路径(因为它需要知道它们才能在每次 sdcard 时重新扫描)所以我想知道是否有办法获取这些路径并使用它们向用户。

获取这些路径的另一个选项(但我不喜欢它)是在 MediaStore 中查询库中的所有音乐并循环它们以获取公共基本路径。但如果用户拥有超过 1/2k 的音乐,这将是一种巨大且未优化的方式。

你知道我该如何解决吗?

我也在考虑列出 sdcard 中的所有文件夹和文件,但我遇到了一些递归问题,因为我不想显示:

  • 不是音频文件(已使用 FileFilter 完成)
  • 不显示空文件夹(已经完成但有递归问题)
  • 不显示带有 .nomedia 文件的文件夹(这告诉我没有任何媒体文件,但存在递归问题)。其他应用程序创建的许多文件夹也没有放置 .nomedia 文件,所以我必须向它们展示

您对此有何看法?

更新:我想做的是这样的:https://play.google.com/store/apps/details?id=cyberniko.musicFolderPlayer 我想显示有音乐的文件夹,并允许用户开始在选定的文件夹中播放音乐。

【问题讨论】:

    标签: android android-music-player


    【解决方案1】:

    我所说的一种可能的解决方案是使用我编写的 FileFilter 开始扫描 SDCard 中的所有目录:

    此 AudioFilter 应用于返回所有歌曲文件的目录(检查扩展名)以及包含歌曲但不包含 .nomedia 的所有目录

    这个解决方案,无论如何,需要跳过,因为加载dir列表需要太长时间(因为递归alg)

    package com.designfuture.music.util;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.io.FilenameFilter;
    import java.util.ArrayList;
    
    import com.designfuture.framework.util.LogHelper;
    
    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 checkDirectory( f );
            }
            return checkFileExtension( f );
        }
    
        private boolean checkFileExtension( File f ) {
            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; 
        }
    
        private boolean checkDirectory( File dir ) {
            if ( !allowDirectories ) {
                return false;
            } else {
                final ArrayList<File> subDirs = new ArrayList<File>();
                int songNumb = dir.listFiles( new FileFilter() {
    
                    @Override
                    public boolean accept(File file) {
                        if ( file.isFile() ) {
                            if ( file.getName().equals( ".nomedia" ) )
                                return false;
    
                            return checkFileExtension( file );
                        } else if ( file.isDirectory() ){
                            subDirs.add( file );
                            return false;
                        } else
                            return false;
                    }
                } ).length;
    
                if ( songNumb > 0 ) {
                    LogHelper.i(TAG, "checkDirectory: dir " + dir.toString() + " return true con songNumb -> " + songNumb );
                    return true;
                }
    
                for( File subDir: subDirs ) {
                    if ( checkDirectory( subDir ) ) {
                        LogHelper.i(TAG, "checkDirectory [for]: subDir " + subDir.toString() + " return true" );
                        return true;
                    }
                }
                return false;
            }       
        }
    
        private boolean checkFileExtension( String fileName ) {
            String ext = getFileExtension(fileName);
            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 ) {
            return getFileExtension( f.getName() );
        }
    
        public String getFileExtension( String fileName ) {
            int i = fileName.lastIndexOf('.');
            if (i > 0) {
                return fileName.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;
            }
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      MediaStore 已经知道要遵循的正确路径(因为它需要知道它们才能在每次 sdcard 时重新扫描)所以我想知道是否有办法获取这些路径并使用它们向用户。

      MediaStore 扫描所有外部存储、AFAIK,而不仅仅是某些特定的根文件夹。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-13
        相关资源
        最近更新 更多