Android external storage

2019-07-17 00:57发布

问题:

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?

回答1:

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.