Improve the constructor API in MediaAdapter

This commit is contained in:
Christopher Eby 2010-05-15 23:25:21 -05:00
parent 5b69fcfc3c
commit 7090c468aa
3 changed files with 108 additions and 22 deletions

View File

@ -42,14 +42,28 @@ import android.widget.CursorAdapter;
import android.widget.Filter;
import android.widget.FilterQueryProvider;
/**
* MediaAdapter provides an adapter backed by a MediaStore content provider.
* It generates simple one- or two-line text views to display each media
* element.
*
* Filtering is supported, as is a more specific type of filtering referred to
* as limiting. Limiting is separate from filtering; a new filter will not
* erase an active filter. Limiting is intended to allow only media belonging
* to a specific group to be displayed, e.g. only songs from a certain artist.
* See MediaView.getLimiter and setLimiter for details.
*/
public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
public static final String[] ARTIST_FIELDS = { MediaStore.Audio.Artists.ARTIST };
public static final String[] ARTIST_FIELD_KEYS = { MediaStore.Audio.Artists.ARTIST_KEY };
public static final String[] ALBUM_FIELDS = { MediaStore.Audio.Albums.ARTIST, MediaStore.Audio.Albums.ALBUM };
// Why is there no artist_key column constant in the album MediaStore? The column does seem to exist.
public static final String[] ALBUM_FIELD_KEYS = { "artist_key", MediaStore.Audio.Albums.ALBUM_KEY };
public static final String[] SONG_FIELDS = { MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE };
public static final String[] SONG_FIELD_KEYS = { MediaStore.Audio.Media.ARTIST_KEY, MediaStore.Audio.Media.ALBUM_KEY, MediaStore.Audio.Media.TITLE_KEY };
/**
* Type indicating that MediaStore.Audio.Artists should be used as the
* provider backing this adapter.
*/
public static final int TYPE_ARTIST = 1;
/**
* Type indicating that MediaStore.Audio.Albums should be used as the
* adapter backing this adapter.
*/
public static final int TYPE_ALBUM = 2;
Uri mStore;
String[] mFields;
@ -58,17 +72,18 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
private String[] mLimiter;
private CharSequence mConstraint;
public MediaAdapter(Context context, Uri store, String[] fields, String[] fieldKeys, boolean expandable)
/**
* Perform required setup during construction. See constructors for
* details.
*/
private void init(Context context, Uri store, String[] fields, String[] fieldKeys, boolean expandable)
{
super(context, null, true);
mStore = store;
mFields = fields;
mFieldKeys = fieldKeys;
mExpandable = expandable;
setFilterQueryProvider(this);
requery();
if (mPaint == null) {
@ -82,6 +97,65 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
}
}
/**
* Construct a MediaAdapter representing an arbitrary media content
* provider.
*
* @param context A Context to use
* @param store The external content uri of the provider
* @param fields The fields to use in the provider. The last field will be
* displayed as the first line in views. If more than one field is given,
* the first field will be displayed as the bottom line.
* @param fieldKeys The sorting keys corresponding to each field from
* <code>fields</code>. Used for filtering.
* @param expandable Whether an expand arrow should be shown to the right
* of the views' text
* @param requery If true, automatically update the adapter when the
* provider backing it changes
*/
protected MediaAdapter(Context context, Uri store, String[] fields, String[] fieldKeys, boolean expandable, boolean requery)
{
super(context, null, requery);
init(context, store, fields, fieldKeys, expandable);
}
/**
* Construct a MediaAdapter representing the given <code>type</code> of
* media.
*
* @param context A Context to use
* @param type The type of media; one of TYPE_ALBUM or TYPE_ARTIST
* @param expandable Whether an expand arrow should be shown to the right
* of the views' text
* @param requery If true, automatically update the adapter when the
* provider backing it changes
*/
public MediaAdapter(Context context, int type, boolean expandable, boolean requery)
{
super(context, null, requery);
Uri store;
String[] fields;
String[] fieldKeys;
switch (type) {
case TYPE_ARTIST:
store = MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI;
fields = new String[] { MediaStore.Audio.Artists.ARTIST };
fieldKeys = new String[] { MediaStore.Audio.Artists.ARTIST_KEY };
break;
case TYPE_ALBUM:
store = MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI;
fields = new String[] { MediaStore.Audio.Albums.ARTIST, MediaStore.Audio.Albums.ALBUM };
// Why is there no artist_key column constant in the album MediaStore? The column does seem to exist.
fieldKeys = new String[] { "artist_key", MediaStore.Audio.Albums.ALBUM_KEY };
break;
default:
throw new IllegalArgumentException("Invalid value for type: " + type);
}
init(context, store, fields, fieldKeys, expandable);
}
public final void requery()
{
changeCursor(runQuery(mConstraint));
@ -195,12 +269,6 @@ public class MediaAdapter extends CursorAdapter implements FilterQueryProvider {
return mLimiter.length;
}
@Override
protected void onContentChanged()
{
// do nothing; we implement this in SongSelector
}
@Override
public void bindView(View view, Context context, Cursor cursor)
{

View File

@ -21,10 +21,28 @@ package org.kreed.vanilla;
import android.content.Context;
import android.provider.MediaStore;
/**
* Subclasses MediaAdapter to represent songs. Providers some song-specific
* logic over plain MediaAdapter: exclusion of non-music media files and
* better sorting inside albums.
*/
public class SongMediaAdapter extends MediaAdapter {
public SongMediaAdapter(Context context)
/**
* Construct a MediaAdapter backed by MediaStore.Audio.Media.
*
* @param context A Context to use
* @param expandable Whether an expander arrow should by shown to the right
* of views
* @param requery If true, automatically update the adapter when the
* provider changes
*/
public SongMediaAdapter(Context context, boolean expandable, boolean requery)
{
super(context, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, SONG_FIELDS, SONG_FIELD_KEYS, false);
super(context,
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
new String[] { MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.TITLE },
new String[] { MediaStore.Audio.Media.ARTIST_KEY, MediaStore.Audio.Media.ALBUM_KEY, MediaStore.Audio.Media.TITLE_KEY },
expandable, requery);
}
@Override

View File

@ -413,9 +413,9 @@ public class SongSelector extends PlaybackActivity implements AdapterView.OnItem
{
switch (message.what) {
case MSG_INIT:
setupView(R.id.artist_list, new MediaAdapter(this, MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, MediaAdapter.ARTIST_FIELDS, MediaAdapter.ARTIST_FIELD_KEYS, true));
setupView(R.id.album_list, new MediaAdapter(this, MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, MediaAdapter.ALBUM_FIELDS, MediaAdapter.ALBUM_FIELD_KEYS, true));
setupView(R.id.song_list, new SongMediaAdapter(this));
setupView(R.id.artist_list, new MediaAdapter(this, MediaAdapter.TYPE_ARTIST, true, false));
setupView(R.id.album_list, new MediaAdapter(this, MediaAdapter.TYPE_ALBUM, true, false));
setupView(R.id.song_list, new SongMediaAdapter(this, false, false));
ContentResolver resolver = getContentResolver();
Observer observer = new Observer(mHandler);