【问题标题】:Android MediaStore get distinct folders of music filesAndroid MediaStore 获得不同的音乐文件文件夹
【发布时间】:2012-07-01 20:11:25
【问题描述】:

寻找仅从 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));

因此,我们将在songs 列表中拥有类似:

/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

我真正在寻找什么 - 从 dirPath 获取这样的 DISTINCT 一级嵌套路径列表,如下所示:

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

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

有什么想法吗?

编辑 我找到了两种可能的解决方案: Android list music by folders and play themConstruct a tree structure from list of string paths ,但我认为解决这个问题的更好方法是可能的。

【问题讨论】:

    标签: android sql sqlite


    【解决方案1】:

    您必须同时使用这两种技术。 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"/>
    

    【讨论】:

    • 悲伤的演示。在线返回 logcat 错误:list = file.listFiles(new AudioFilter());
    • 正是我想要的。这个答案应该有更多的赞成票。做得很好。
    【解决方案2】:

    这是我的解决方案。

    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. 数组是一个不同的文件夹列表

    【讨论】:

    • 我对代码进行了一些调整,使其更易于阅读;你能检查并确保我没有删除任何增加意义的东西吗?
    【解决方案3】:
    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;
    
        }
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-29
        • 2021-08-03
        • 1970-01-01
        • 2012-06-09
        • 1970-01-01
        • 1970-01-01
        • 2017-11-29
        • 1970-01-01
        相关资源
        最近更新 更多