Вопрос по android – Android перечисляет музыку по папкам и воспроизводит их

2

Я разрабатываю музыкальный проигрыватель для Android, который уже есть в продаже. Пользователи просят добавить представление «Папка», чтобы отобразить список всех папок, в которых есть музыка на смартфоне, и я хочу ее разработать.

MediaStore уже знает, какие правильные пути следует использовать (потому что он должен знать их для повторного сканирования каждый раз sdcard), поэтому мне было интересно, есть ли способ получить эти пути и использовать их для показа музыки пользователю.

Другие варианты (но мне это не нравится), чтобы получить эти пути, это запросить MediaStore для всей музыки в библиотеке и выполнить цикл для получения общих базовых путей. Но если у пользователя более 1 / 2k музыки, это будет огромный и неоптимизированный способ.

Вы знаете, как я могу решить это?

Я также занимался перечислением всех папок и файлов на SD-карте, но столкнулся с некоторой рекурсивной проблемой, потому что хочу не показывать:

not audio file (already done with a FileFilter) not show empty folders (already done but has the recursive problem) not show folders with .nomedia file (that tells me that there aren't any media files, but has the recursive problem). Also many folders created by others application don't put the .nomedia file, so I've to show them

Что Вы думаете об этом?

UPDATEЯ хочу сделать что-то вроде этого:https://play.google.com/store/apps/details?id=cyberniko.musicFolderPlayer Я хочу показать папки, в которых есть музыка, и позволить пользователю начать воспроизведение музыки в выбранных папках.

Ваш Ответ

2   ответа
1

MediaStore already know which are the correct paths to follow (because it needs to know them to re-scan every times the sdcard) so I was wondering if there is a way to get those paths and use them to show music to the user.

MediaStore сканирует все внешнее хранилище, AFAIK, а не только определенные корневые папки.

1

Как я уже сказал, одно из возможных решений - начать сканирование всех каталогов с SDCard с помощью этого FileFilter, который я написал:

Этот AudioFilter применяется к каталогу, который возвращает все файлы, которые являются песней (проверка расширений), и все каталоги, которые содержат песню и не содержат .nomedia

В любом случае, это решение нужно пропустить, потому что загрузка списка директорий занимает слишком много времени (из-за рекурсивного алгоритма)

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

}

Похожие вопросы