2012-07-01 21 views
5

Buscando la manera de obtener solo rutas de carpeta de archivos de música de Android MediaStore para la ruta del directorio ingresado. Así que en realidad la pregunta es sobre cómo hacer una consulta adecuada a MediaStore.Android MediaStore obtiene distintas carpetas de archivos de música

Aquí hay un ejemplo. Mi código actual:

String dirPath="/mnt/sdcard/Music/"; 
    String selection =MediaStore.Audio.Media.DATA +" like ?"; 
    String[] projection = {MediaStore.Audio.Media.DATA};  
    String[] selectionArgs={dirPath+"%"}; 
    Cursor cursor = this.managedQuery(
     MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
     projection, 
     selection, 
     selectionArgs, 
     null); 
    List<String> songs = new ArrayList<String>(); 
    while(cursor.moveToNext()) 
     songs.add(cursor.getString(0)); 

Como resultado tendremos en el Smth songs lista como:

/mnt/sdcard/Music/song1.mp3 
/mnt/sdcard/Music/song2.mp3 
/mnt/sdcard/Music/FolderWithSongs/song3.mp3 
/mnt/sdcard/Music/AnotherFolderWithSongs/song4.mp3 
/mnt/sdcard/Music/AndOneMoreFolder/song5.mp3 
/mnt/sdcard/Music/AndOneMoreFolder/song6.mp3 
/mnt/sdcard/Music/AndOneMoreFolder/song7.mp3 
/mnt/sdcard/Music/AndOneMoreFolder/SomeFolder/song8.mp3 
/mnt/sdcard/Music/AndOneMoreFolder/SomeFolder/song9.mp3 

Lo que estoy realmente buscando - para obtener dichas listas distintas de un solo nivel caminos anidados de dirPath como este:

/mnt/sdcard/Music/FolderWithSongs/ 
/mnt/sdcard/Music/AnotherFolderWithSongs/ 
/mnt/sdcard/Music/AndOneMoreFolder/ 

Si aquí serán los archivos de la carpeta actual - /mnt/sdcard/Music/song1.mp3 y /mnt/sdcard/Music/song2.mp3 - también es aceptable.

¿Alguna idea?

EDITAR he encontrado dos soluciones posibles: Android list music by folders and play them y Construct a tree structure from list of string paths , pero creo que mejor manera de resolver este problema es posible.

Respuesta

0

Esto puede obras: - utilizar el método walkDir para buscar todos los archivos de música en su lugar de almacenamiento, entonces se podría obtener la ruta de cada archivo de getPath() método - método de uso subsString() con todos los ficheros de camino para llegar el nombre de la carpeta de nivel 1 - almacenar todo el nombre de la carpeta en una ArrayList el uso de Hashset para eliminar el nombre de la carpeta duplicada (con condición)

2

Esta es mi solución.

  1. analizar todos los archivos de audio ex) Cursor mCursor = getContentResolver().query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ...
  2. declarar nueva matriz
  3. bucle
  4. nombre de carpeta = MediaStore.Audio.Media.DATA - MediaStore.Audio.Media.DISPLAY_NAME
  5. poner el nuevo en la variable de matriz
  6. matriz es una lista de carpetas distinta
+0

He retocado el código un poco por lo que es más fácil de leer; ¿Puedes verificar y asegurarte de que no he eliminado nada que agregue significado? – andrewsi

+0

@andrewsi, bien. Gracias. – jeonggu

+0

¿Algún código de ejemplo en github? – TheOnlyAnil

9

Deberá usar ambas técnicas. MediaStore y explorador de archivos.

public class MainActivity extends ActionBarActivity { 
private File file; 
private List<String> myList; 
private ListView listView; 
private TextView pathTextView; 
private String mediapath = new String(Environment.getExternalStorageDirectory().getAbsolutePath()); 

private final static String[] acceptedExtensions= {"mp3", "mp2", "wav", "flac", "ogg", "au" , "snd", "mid", "midi", "kar" 
    , "mga", "aif", "aiff", "aifc", "m3u", "oga", "spx"}; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    listView=(ListView) findViewById(R.id.pathlist); 
    pathTextView=(TextView) findViewById(R.id.path); 

    myList = new ArrayList<String>(); 

    String root_sd = Environment.getExternalStorageDirectory().toString(); 
    Log.e("Root",root_sd); 

    String state = Environment.getExternalStorageState(); 
    File list[] = null ; 
    /* if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { // we can read the External Storage... 
     list=getAllFilesOfDir(Environment.getExternalStorageDirectory()); 
    }*/ 

    pathTextView.setText(root_sd); 

    file = new File(root_sd) ;  
    list = file.listFiles(new AudioFilter()); 
    Log.e("Size of list ","" +list.length); 
    //LoadDirectory(root_sd); 

    for(int i=0; i< list.length; i++) 
    { 

     String name=list[i].getName(); 
    int count =  getAudioFileCount(list[i].getAbsolutePath()); 
    Log.e("Count : "+count, list[i].getAbsolutePath()); 
    if(count!=0) 
    myList.add(name); 
     /*int count=getAllFilesOfDir(list[i]); 
     Log.e("Songs count ",""+count); 

     */ 

    } 


    listView.setAdapter(new ArrayAdapter<String>(this, 
      android.R.layout.simple_list_item_1, myList)); 

    listView.setOnItemClickListener(new OnItemClickListener() { 

     @Override 
     public void onItemClick(AdapterView<?> arg0, View arg1, int position, 
       long arg3) { 
      File temp_file = new File(file, myList.get(position)); 

      if(!temp_file.isFile())   
      { 
       //LoadDirectory(myList.get(position)); 

       file = new File(file, myList.get(position)); 
       File list[] = file.listFiles(new AudioFilter()); 

       myList.clear(); 

       for(int i=0; i< list.length; i++) 
       { 
        String name=list[i].getName(); 

        int count =  getAudioFileCount(list[i].getAbsolutePath()); 
         Log.e("Count : "+count, list[i].getAbsolutePath()); 
         if(count!=0) 
         myList.add(name); 
        /*int count=getAllFilesOfDir(list[i]); 
        Log.e("Songs count ",""+count); 
        if(count!=0) 
         myList.add(name);*/ 
       } 

       pathTextView.setText(file.toString()); 
       //Toast.makeText(getApplicationContext(), file.toString(), Toast.LENGTH_LONG).show(); 
       listView.setAdapter(new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, myList)); 

      } 


     } 
    }); 



} 

private int getAudioFileCount(String dirPath) { 

     String selection =MediaStore.Audio.Media.DATA +" like ?"; 
     String[] projection = {MediaStore.Audio.Media.DATA};  
     String[] selectionArgs={dirPath+"%"}; 
     Cursor cursor = this.managedQuery(
      MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
      projection, 
      selection, 
      selectionArgs, 
      null); 
     return cursor.getCount(); 
    } 


@Override 
public void onBackPressed() { 
    try { 
     String parent = file.getParent().toString(); 
     file = new File(parent) ;   
     File list[] = file.listFiles(new AudioFilter()); 

     myList.clear(); 

     for(int i=0; i< list.length; i++) 
     { 
      String name=list[i].getName(); 
      int count =  getAudioFileCount(list[i].getAbsolutePath()); 
       Log.e("Count : "+count, list[i].getAbsolutePath()); 
       if(count!=0) 
       myList.add(name); 
      /*int count=getAllFilesOfDir(list[i]); 
      Log.e("Songs count ",""+count); 
      if(count!=0)*/ 

     } 
     pathTextView.setText(parent); 
    // Toast.makeText(getApplicationContext(), parent,   Toast.LENGTH_LONG).show(); 
     listView.setAdapter(new ArrayAdapter<String>(this, 
       android.R.layout.simple_list_item_1, myList)); 
    } catch (Exception e) { 
     finish(); 
    } 


} 



// class to limit the choices shown when browsing to SD card to media files 
public class AudioFilter implements FileFilter { 

    // only want to see the following audio file types 
    private String[] extension = {".aac", ".mp3", ".wav", ".ogg", ".midi", ".3gp", ".mp4", ".m4a", ".amr", ".flac"}; 

    @Override 
    public boolean accept(File pathname) { 

     // if we are looking at a directory/file that's not hidden we want to see it so return TRUE 
     if ((pathname.isDirectory() || pathname.isFile()) && !pathname.isHidden()){ 
      return true; 
     } 

     // loops through and determines the extension of all files in the directory 
     // returns TRUE to only show the audio files defined in the String[] extension array 
     for (String ext : extension) { 
      if (pathname.getName().toLowerCase().endsWith(ext)) { 
       return true; 
      } 
     } 

     return false; 
    }  
} 



} 

archivo .xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 

<TextView 
    android:textSize="21sp" 
    android:typeface="monospace" 
    android:id="@+id/path" 
    android:layout_width="fill_parent" 
    android:layout_height="100dp" 
    android:layout_margin="10dp" 
    android:gravity="bottom" 
    android:text="PATH : " /> 

<View 
    android:layout_width="fill_parent" 
    android:layout_height="2dp" 
    android:background="#111111" /> 

<ListView android:id="@+id/pathlist" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 
</ListView> 

</LinearLayout> 

permisos en el archivo de Manifiesto:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
+0

Triste demo. Devuelve el error de logcat en línea: list = file.listFiles (nuevo AudioFilter()); – TheOnlyAnil

+0

funciona perfecto en mi dispositivo –

+1

Exactamente, lo que estaba buscando. Esta respuesta debería tener más votos ascendentes. Bien hecho. – crysis

Cuestiones relacionadas