2

I'm using method Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) to get the default directory my Android device saves its music to.

The directory returned by this method exists(something like sdcard/music), but it doesn't have any music files. When I checked my sdcard I found all the music files are instead stored in another directory named by one of my applications(sdcard/qqmusic/song), which cannot be found using the getExternalStoragePublicDirectory method.

In such case(different devices store music in different locations), is there any good ways to get the paths regardless of the differences among devices?

hexacyanide
  • 88,222
  • 31
  • 159
  • 162
Allen
  • 47
  • 7
  • It is wise to let user tell you where those music files is. – StarPinkER Mar 17 '13 at 04:22
  • I think most users won't care about where their devices save music files. – Allen Mar 17 '13 at 08:15
  • But obviously that music is downloaded by qqmusic which is a popular app in China. And that directory is created by that application. – StarPinkER Mar 17 '13 at 08:38
  • when i open the original android music player, it can display all the songs in my phone without asking me which app I'm using...I wonder if there is a filter or something that can filter out all the music. – Allen Mar 18 '13 at 01:27
  • Yes, the original Android Music search all the directory under sdcard. I can post the source code if you like. – StarPinkER Mar 18 '13 at 02:22
  • Yeah, I'd love to have a look. Thank you Jermaine. – Allen Mar 18 '13 at 13:44

1 Answers1

0

As we discussed in comments, I'll show how Android Music application find all music files.

Android Music application simply query the MediaProvider to get all musics on external storage, i.e. sdcard.

And the databases is filled by MediaScannerService. The MediaScannerService call the MediaScanner.scanDirectories to search all files under those directories. Fetch metadata if it is audio file and put it into database(MediaProvider).

if (MediaProvider.INTERNAL_VOLUME.equals(volume)) {
    // scan internal media storage
    directories = new String[] {
        Environment.getRootDirectory() + "/media",
    };
}else if (MediaProvider.EXTERNAL_VOLUME.equals(volume)) {
    // scan external storage volumes
    directories = mExternalStoragePaths;
}

if (directories != null) {
    scan(directories, volume);
}

So my answer is the MediaProvider already contains the music files on the external storage, so you can directly query the provider to get all music files.

Check MediaStore first.

You can use the following code to get all music files.

//Some audio may be explicitly marked as not being music
String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

String[] projection = {
        MediaStore.Audio.Media._ID,
        MediaStore.Audio.Media.ARTIST,
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.DATA,
        MediaStore.Audio.Media.DISPLAY_NAME,
        MediaStore.Audio.Media.DURATION
};

cursor = this.managedQuery(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        null,
        null);

private List<String> songs = new ArrayList<String>();
    while(cursor.moveToNext()){
        songs.add(cursor.getString(0) + "||" + cursor.getString(1) + "||" +   cursor.getString(2) + "||" +   cursor.getString(3) + "||" +  cursor.getString(4) + "||" +  cursor.getString(5));
}

The MediaStore.Audio.Media.DATA column contains the full path to that music file.

StarPinkER
  • 14,081
  • 7
  • 55
  • 81
  • I can understand the cursor part, but the MediaProvider part confuses me. Could you please explain in some detail? – Allen Mar 19 '13 at 13:41
  • The EXTERNAL_VOLUME means the sdcard in general, and the scan(...) method calls the scanDirectory method in MediaScanner, I've posted the source code of MediaScanner, you can take a look at it. @Allen – StarPinkER Mar 20 '13 at 00:19