寻找从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 them 和Construct a tree structure from list of string paths ,但我认为解决这个问题的更好方法是可能的。
答案 0 :(得分: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"/>
答案 1 :(得分:2)
这是我的解决方案。
Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ...
MediaStore.Audio.Media.DATA - MediaStore.Audio.Media.DISPLAY_NAME
答案 2 :(得分:0)
这可能有效: - 使用walkDir方法搜索存储位置中的所有音乐文件,然后您可以从getPath()方法获取每个文件的路径 - 将subsString()方法与所有路径文件一起使用以获取1级文件夹名称 - 将所有文件夹名称存储在ArrayList中,使用Hashset删除重复的文件夹名称(带条件)
答案 3 :(得分:0)
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;
}