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.

Était-ce utile?

La 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...

Autres conseils

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...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top