5

寻找仅从 Android MediaStore 获取音乐文件的文件夹路径以获取输入目录路径的方法。所以实际上的问题是关于如何对 MediaStore 进行正确的查询。

这是一个例子。我当前的代码:

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

结果,我们将在songsList smth 中拥有:

/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

我实际上在寻找什么 - 从这样的 DISTINCT 一级嵌套路径列表中获取dirPath

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

如果这里是当前文件夹文件 -/mnt/sdcard/Music/song1.mp3并且 /mnt/sdcard/Music/song2.mp3- 这也是可以接受的。

有任何想法吗?

编辑 我找到了两种可能的解决方案: Android 按文件夹列出音乐并播放它们从字符串路径列表构造树结构 ,但我认为解决这个问题的更好方法是可能的。

4

4 回答 4

10

您将不得不同时使用这两种技术。MediaStore 和文件资源管理器。

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



}

.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>

清单文件中的权限:

 <uses-permission  android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
于 2015-02-12T09:27:59.367 回答
3

这是我的解决方案。

  1. 扫描所有音频文件前)Cursor mCursor = getContentResolver().query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ...
  2. 声明新数组
  3. 环形
  4. 文件夹名称 =MediaStore.Audio.Media.DATA - MediaStore.Audio.Media.DISPLAY_NAME
  5. 将新的放入数组变量
  6. array 是一个不同的文件夹列表
于 2013-11-11T16:06:59.277 回答
1
public ArrayList<String> Get_Folder_Paths() {

         String[] columns = {
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.TITLE,
            MediaStore.Audio.Media.ARTIST,
            MediaStore.Audio.Media.DURATION,
            MediaStore.Audio.Media.DATA,
            MediaStore.Audio.Media.ALBUM,
            MediaStore.Audio.Media.ALBUM_ID,
            MediaStore.Audio.Media.TRACK,
            MediaStore.Audio.Media.ARTIST_ID,
            MediaStore.Audio.Media.DISPLAY_NAME,

    };

        ArrayList<String> FoldersList = new ArrayList<>();

        ArrayList<String> DATAList = new ArrayList<>();
        ArrayList<String> DISPLAY_NAMEList = new ArrayList<>();

        Cursor cursor = this.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                columns(),
                MediaStore.Audio.Media.IS_MUSIC + " = 1", null, null);
        if (cursor.moveToFirst()) {
            do {
                DATAList.add(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
                DISPLAY_NAMEList.add(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)));
            } while (cursor.moveToNext());
        }

        for (int i = 0; i < DATAList.size(); i++) {
            FoldersList.add(DATAList.get(i).replace(DISPLAY_NAMEList.get(i), ""));

        }

        HashSet hs = new HashSet();

        hs.addAll(FoldersList); // demoArrayList= name of arrayList from which u want to remove duplicates

        FoldersList.clear();
        FoldersList.addAll(hs);

        if (cursor != null) {
            cursor.close();
        }
        return FoldersList;

    }
于 2020-02-05T04:01:39.103 回答
0

这可能有效: - 使用 walkDir 方法搜索存储位置中的所有音乐文件,然后您可以从 getPath() 方法获取每个文件的路径 - 对所有路径文件使用 subsString() 方法来获取 1 级文件夹名称 -将所有文件夹名称存储在 ArrayList 中,使用 Hashset 删除重复的文件夹名称(有条件)

于 2013-07-03T09:22:56.390 回答