2

私はすでに市場に出ているアンドロイド用の音楽プレーヤーを開発しています。ユーザーは、スマートフォンに音楽があるすべてのフォルダーを一覧表示するフォルダー ビューを追加するよう求めており、私はそれを開発したいと考えています。

MediaStore は、従うべき正しいパスを既に知っているため (SD カードを再スキャンするたびにパスを知る必要があるため)、それらのパスを取得してユーザーに音楽を表示する方法があるかどうか疑問に思っていました。

これらのパスを取得する別のオプション (ただし、私は好きではありません) は、ライブラリ内のすべての音楽について MediaStore にクエリを実行し、それらをループして共通の基本パスを取得することです。しかし、ユーザーが 1/2k 以上の音楽を持っている場合、それは巨大で最適化されていない方法になります。

どうすれば解決できるか知っていますか?

SDカード内のすべてのフォルダーとファイルをリストすることについても考えていましたが、表示したくないため、再帰的な問題が発生しています。

  • 音声ファイルではありません (既に FileFilter で処理済み)
  • 空のフォルダーを表示しない (既に行われていますが、再帰的な問題があります)
  • .nomedia ファイルを含むフォルダーを表示しません (これは、メディア ファイルがないことを示していますが、再帰的な問題があることを示しています)。また、他のアプリケーションによって作成された多くのフォルダーには .nomedia ファイルが配置されていないため、それらを表示する必要があります

これについてあなたはどう思いますか?

更新: 私がやりたいことは次のようなものです: https://play.google.com/store/apps/details?id=cyberniko.musicFolderPlayer音楽のあるフォルダーを表示し、ユーザーが再生を開始できるようにしたい選択したフォルダ内の音楽。

4

2 に答える 2

1

MediaStore は、従うべき正しいパスを既に知っているため (SD カードを再スキャンするたびにそれらを知る必要があるため)、それらのパスを取得し、それらを使用してユーザーに音楽を表示する方法があるかどうか疑問に思っていました。

MediaStore一部の特定のルートフォルダーだけでなく、AFAIKのすべての外部ストレージをスキャンします。

于 2012-06-06T10:33:35.603 に答える
1

私が言ったように、考えられる解決策の 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;
        }
    }

}
于 2012-06-05T13:28:00.297 に答える