Pages

Friday, July 1, 2011

How to get distinct values from android mediastore using contentresolver


In this post we can see a very easy way to get a list of distinct values from the android's Mediastore. In past I need that, but I haven't found an easy solution when I search for this to the Internet. So I found a solution and I show you with a  small tutorial.(It's my first attemp).


We say that we want to get the distinct values of the years*, which we have at least one song recorded.
So we create an new activity(I hope to know how, else the internet is full of  tutorials) and into the onCreate method we put our code.

1:          // get the content resolver instance  
2:          ContentResolver contentResolver = getContentResolver();  
3:          // the column of the year  
4:          final String year = MediaStore.Audio.AudioColumns.YEAR;  
5:          // create the string array with the returned values, there is the trick  
6:          // we use the DISTINCT before the name of the column  
7:          String[] values = new String[] { "DISTINCT " + year };  
8:          // execute the query  
9:          // we also check not to get null values  
10:          Cursor cursor = contentResolver  
11:                  .query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,  
12:                         values,year + " not null", null,  
13:                         MediaStore.Audio.AudioColumns.YEAR);  
14:          // for each returned row we printed using android Logging fuctions  
15:          // we use loggat with tag distinct to see the result  
16:          // also you can show the results in the gui of your app  
17:          while (cursor.moveToNext()) {  
18:              Log.d("distinct", "year " + cursor.getString(0));  
19:          }  


*You can see the columns about audios in the mediastore from here http://developer.android.com/reference/android/provider/MediaStore.Audio.AudioColumns.html

5 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. I am try with your code!
    But it didn't work!
    Please! help me
    This is my code
    cursor = getContentResolver().query(
    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
    new String[]{ "DISTINCT "
    +MediaStore.Audio.Media.ALBUM},
    null,
    null, MediaStore.Audio.Media.ALBUM);

    ReplyDelete
  3. this doesn't work...

    but the following code will:

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

    public Map getAlbumList(Context c) {
    //setup map and cursor
    Map result = new HashMap();
    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....

    ReplyDelete