2012-06-05 3 views
2

나는 이미 시판중인 안드로이드 용 뮤직 플레이어를 개발 중입니다. 사용자는 스마트 폰에 음악이있는 모든 폴더를 나열하기 위해 폴더보기를 추가해야하며이를 개발하고 싶습니다.안드로이드는 폴더별로 음악을 나열하고 재생합니다.

MediaStore는 어떤 경로가 올바른지 알고 있습니다 (매번 sdcard를 다시 검색해야하므로 MediaStore는이를 알고 있습니다.) 그래서 경로를 가져 와서 음악을 보여줄 방법이 있는지 궁금 해서요. 사용자.

이러한 경로를 얻는 또 다른 옵션은 (하지만 마음에 들지 않습니다.) 라이브러리의 모든 음악을 MediaStore에 쿼리하고 공통 기본 경로를 얻기 위해 루프를 반복하는 것입니다. 그러나 사용자가 1/2k 이상의 음악을 가지고 있다면 그것은 거대하고 최적화되지 않은 방법이 될 것입니다.

어떻게 해결할 수 있습니까?

내가 보여주지 원하기 때문에 나는 또한 SDCARD에있는 모든 폴더와 파일 목록에 대해 thingking했지만, 난 어떤 재귀 문제에서 발생하고있어 (이미 FileFilter를 함께 할)

  • 하지 오디오 파일을
  • 빈 폴더를 표시하지 않음 (이미 완료되었지만 재귀 문제가 있음)
  • .nomedia 파일이있는 폴더가 표시되지 않습니다 (미디어 파일이 없지만 재귀 문제가 있음을 나타냄). 또한 다른 응용 프로그램에서 만든 많은 폴더는 .nomedia 파일을 두지 않으므로 표시해야합니다.

당신은 어떻게 생각하십니까?

UPDATE는 : https://play.google.com/store/apps/details?id=cyberniko.musicFolderPlayer 내가 거기에 어떤 음악을하고 사용자가 선택한 폴더에 음악을 재생 시작할 수 있도록 폴더를 표시하려면 : 제가하고 싶은 것은이 같은 것입니다.

답변

1

한 가지 가능한 해결책 나는 내가 쓴이되는 FileFilter으로 SDCard에 모든 디렉토리를 스캔을 시작하는 것입니다 말했듯이 :

을이 AudioFilter이 노래가 모든 파일 (확장자 확인) 반환하는 디렉토리에 적용되고 노래를 포함하고 모든 디렉토리가 .nomedia

에게이 솔루션을 포함는 (때문에 재귀 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; 
     } 
    } 

} 
1
생략해야

MediaStore는 어떤 경로가 올바른지 알고 있습니다 (매번 sdcard를 다시 스캔해야하기 때문에). 따라서 경로를 가져 와서 사용자에게 음악을 보여줄 수있는 방법이 있는지 궁금합니다. .

MediaStore 일부 특정 루트 폴더뿐만 아니라 외부 저장소 AFAIK도 모두 검사합니다.