Reputation: 1551
Looking for the way to get only folder paths of music files from Android MediaStore for inputted directory path. So actually question is about how to make proper query to the MediaStore.
Here is an example. My current code:
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));
As a result we’ll have in the songs
List smth like:
/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
What I’m actually looking for - to get such DISTINCT list of one-level nested paths from dirPath
like this:
/mnt/sdcard/Music/FolderWithSongs/
/mnt/sdcard/Music/AnotherFolderWithSongs/
/mnt/sdcard/Music/AndOneMoreFolder/
If here will be current folder files - /mnt/sdcard/Music/song1.mp3
and
/mnt/sdcard/Music/song2.mp3
– it’s acceptable too.
Any ideas?
EDIT I've found two possible solutions: Android list music by folders and play them and Construct a tree structure from list of string paths , but I think better way to solve this problem is possible.
Upvotes: 7
Views: 8920
Reputation: 2485
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;
}
Upvotes: 0
Reputation: 2318
You will have to use both technique . MediaStore and file explorer .
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 file :
<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>
Permissions in manifiest file :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Upvotes: 9
Reputation: 111
This is my solution.
Cursor mCursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ...
MediaStore.Audio.Media.DATA - MediaStore.Audio.Media.DISPLAY_NAME
Upvotes: 2
Reputation: 69
This may works: - use walkDir method to search all music files in your storage location, then you could get the path of each file from getPath() method - use subsString() method with all path files to get the level 1 folder name - store all folder name in an ArrayList the use Hashset to remove duplicated folder name (with condition)
Upvotes: -1