Question

I am developing a simple audio player in android. I want to list the album's in the device.

I tried this code

String where = new String();
where = MediaStore.Audio.Media.IS_MUSIC + "=1";
private Cursor managedCursor;
managedCursor = managedQuery(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        new String[] {  
            MediaStore.Audio.Media.TITLE,
            MediaStore.Audio.Media._ID,
            MediaStore.Audio.Media.ALBUM,       
            MediaStore.Audio.Media.ALBUM_ID,    
            MediaStore.Audio.Media.ARTIST,
            MediaStore.Audio.Media.ARTIST_ID
        },
        where,                                  
        null,                                       
        MediaStore.Audio.Media.DEFAULT_SORT_ORDER   
    );

  ListAdapter adapter = new AlbumListAdapter(
        this,                                   
        R.layout.albumlist_item,                
        managedCursor,                          
        new String[] {                          
            MediaStore.Audio.Media.ALBUM,       
            MediaStore.Audio.Media.ARTIST           
        },
        new int[] {                             
            R.id.text_album, 
            R.id.text_artist 
        }
    );
    setListAdapter(adapter);

But this code is listing the all the song's in the device.

What is the structure of the Android Media store DB.

Any one please help.

Was it helpful?

Solution

You should query the Albums like this

String[] projection = new String[] { Albums._ID, Albums.ALBUM, Albums.ARTIST, Albums.ALBUM_ART, Albums.NUMBER_OF_SONGS };
String selection = null;
String[] selectionArgs = null;
String sortOrder = Media.ALBUM + " ASC";
Cursor cursor = contentResolver.query(Albums.EXTERNAL_CONTENT_URI, projection, selection, selectionArgs, sortOrder);

http://developer.android.com/reference/android/provider/MediaStore.Audio.Albums.html

Artists, Playlists and Genres can all be queried in a similar way using the correct EXTERNAL_CONTENT_URI and the corresponding projection.

Hope that helps...

OTHER TIPS

use this simplified code to get list of albums

public ArrayList<AlbumModel> getListOfAlbums(Context context) {

            String where = null;

            final Uri uri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
            final String _id = MediaStore.Audio.Albums._ID;
            final String album_name = MediaStore.Audio.Albums.ALBUM;
            final String artist = MediaStore.Audio.Albums.ARTIST;
            final String albumart = MediaStore.Audio.Albums.ALBUM_ART;
            final String tracks = MediaStore.Audio.Albums.NUMBER_OF_SONGS;

            final String[] columns = { _id, album_name, artist, albumart, tracks };
            Cursor cursor = context.getContentResolver().query(uri, columns, where,
                    null, null);

            ArrayList<AlbumModel> list = new ArrayList<AlbumModel>();

            // add playlsit to list

            if (cursor.moveToFirst()) {

                do {

                    AlbumModel albumData = new AlbumModel();

                    albumData
                            .setAlbumID(cursor.getLong(cursor.getColumnIndex(_id)));

                    albumData.setAlbumName(cursor.getString(cursor
                            .getColumnIndex(album_name)));

                    albumData.setALbumArtist(cursor.getString(cursor
                            .getColumnIndex(artist)));

                    albumData.setAlbumArt(cursor.getString(cursor
                            .getColumnIndex(albumart)));

                    albumData.setTracks(cursor.getString(cursor
                            .getColumnIndex(tracks)));

                    list.add(albumData);

                } while (cursor.moveToNext());
            }

            cursor.close();

            return list;
        }
public class Album {

private long id;
private String albumName;
private String artistName;
private int nr_of_songs;
private Bitmap albumImg;

public Album(long id, String albumName, String artistName, Bitmap albumImg,  int nr_of_songs) {
    this.albumImg = albumImg;
    this.id = id;
    this.albumName = albumName;
    this.artistName = artistName;
    this.nr_of_songs = nr_of_songs;
}

public void setId(long id) {
    this.id = id;
}
public void setAlbumName(String albumName) {
    this.albumName = albumName;
}
public void setArtistName(String artistName) {
    this.artistName = artistName;
}
public void setAlbumImg(Bitmap albumImg) {
    this.albumImg = albumImg;
}
public void setNr_of_songs(int nr_of_songs) {
    this.nr_of_songs = nr_of_songs;
}

public long getID(){
    return id;
}
public String getAlbumName(){
    return albumName;
}
public String getArtistName() {
    return artistName;
}
public Bitmap getAlbumImg() {
    return albumImg;
}
public int getNr_of_songs() {
    return nr_of_songs;
}

}


 public void getAlbumsLists(){
    String where = null;

    final Uri uri = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
    final String _id = MediaStore.Audio.Albums._ID;
    final String album_name = MediaStore.Audio.Albums.ALBUM;
    final String artist = MediaStore.Audio.Albums.ARTIST;
    final String albumart = MediaStore.Audio.Albums.ALBUM_ART;
    final String tracks = MediaStore.Audio.Albums.NUMBER_OF_SONGS;

    final String[] columns = { _id, album_name, artist, albumart, tracks };
    Cursor cursor = context.getContentResolver().query(uri, columns, where, null, null);

    if(cursor!=null && cursor.moveToFirst()){

        do {

            long id = cursor.getLong(cursor.getColumnIndex(_id));
            String name = cursor.getString(cursor.getColumnIndex(album_name));
            String artist2 = cursor.getString(cursor.getColumnIndex(artist));
            String artPath = cursor.getString(cursor.getColumnIndex(albumart));
            Bitmap art = BitmapFactory.decodeFile(artPath);
            int nr =Integer.parseInt(cursor.getString(cursor.getColumnIndex(tracks)));

            albumList.add(new Album(id, name, artist2, art, nr));

        } while (cursor.moveToNext());
    }

    cursor.close();
}

This was the original answer

i sorted the unique albums by checking if they had already been added to my map

public Map<String, String> getAlbumList(Context c) {
    //setup map and cursor
    Map<String, String> result = new HashMap<String, String>();
    String selection = MediaStore.Audio.Media.IS_MUSIC + " !=0";
    final Cursor mCursor = c.getContentResolver().query(
            MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            new String[] {MediaStore.Audio.Media.ALBUM,
                    MediaStore.Audio.Media.ARTIST,
                    MediaStore.Audio.Media.ALBUM_ID,}, selection, null,
                   "LOWER ("+MediaStore.Audio.Media.ALBUM + ") ASC");

    int count = mCursor.getCount();


    String[] mArtist = new String[count];
    String[] mAlbum = new String[count];
    String[] AlbumID = new String[count];

    int i = 0;
    int j = 0;
    if (mCursor.moveToFirst()) {

        do {
            mAlbum[i] = mCursor
                    .getString(mCursor
                            .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
            mArtist[i] = mCursor.getString(mCursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));

            AlbumID[i] = Long.toString(mCursor
                    .getLong(mCursor
                            .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID)));

                                    //checking for same previous value
            if(result.containsValue(mAlbum[i])){

            }else{
            result.put("artist" + j, mArtist[i]);
            result.put("album" + j, mAlbum[i]);
            result.put("AlbumID" + j, AlbumID[i]);
            j = j + 1;
            }
            i = i + 1;

        } while (mCursor.moveToNext());
    }

    result.put("count", Integer.toString(j));
    mCursor.close();
    return result;
}
}

perhaps not the prettiest solution to unique sorting of the albums... but it works exactly as intended without fumbling around with sqlite....

i'm passing in a context here because i'm using a listview in a fragment with a custom adapter without the activity context getContentResolver() doesn't work....

addendium to original answer

mArt, mData, mAlbums, and mArtists are Arraylists...

private void getList(View view){
    mArt.clear();
    mAlbums.clear();
    mArtists.clear();

    String[] projection = {"DISTINCT " + MediaStore.Audio.Media.ALBUM_ID,
            MediaStore.Audio.Media.ALBUM,
            MediaStore.Audio.Media.ARTIST

    } ;

    String[] projection2 = {"Distinct " + MediaStore.Audio.Albums.ALBUM,
    MediaStore.Audio.Albums.NUMBER_OF_SONGS};

    Cursor mCursor =  getActivity().getApplicationContext().getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, "0==0 ) GROUP BY (" + MediaStore.Audio.Media.ALBUM_ID, null, MediaStore.Audio.Media.ALBUM + " COLLATE NOCASE ASC");
    Cursor mCursor2 = getActivity().getApplicationContext().getContentResolver().query(MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, projection2, null, null, MediaStore.Audio.Albums.ALBUM + " COLLATE NOCASE ASC");

    if(mCursor != null && mCursor.getCount() > 0 && mCursor2 != null && mCursor2.getCount() > 0){
        CursorJoiner joiner = new CursorJoiner(mCursor, new String[]{MediaStore.Audio.Media.ALBUM},mCursor2, new String[]{MediaStore.Audio.Albums.ALBUM});

        for (CursorJoiner.Result joinerResult : joiner) {
            switch (joinerResult) {
                case LEFT:
                    break;
                case RIGHT:
                    break;
                case BOTH:
                    String songs_s = "Song";
                    int tracks = mCursor2.getInt(mCursor2.getColumnIndex(MediaStore.Audio.Albums.NUMBER_OF_SONGS));
                    if (tracks > 1) {
                        songs_s = "Songs";
                    }
                    mArtists.add(tracks + " " + songs_s + " By " + mCursor.getString(mCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
                    mAlbums.add(mCursor2.getString(mCursor2.getColumnIndex(MediaStore.Audio.Albums.ALBUM)));
                    mArt.add(ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), mCursor.getInt(mCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID))));

            }
        }
    }
    mCursor.close();
    mCursor2.close();
}

the GROUP BY clause in the selection guarantees unique albums, since album art is sotred by the album id this line:

mArt.add(ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), mCursor.getInt(mCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID))));

makes sure that the album art and the album are in the same position...

i am using a cursor joiner here so that I can get the artist, album, and number of songs in the album... this can only be returned from two separate queries...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top