I'm trying to download images for each artist that has music on my phone, then show these images in a GridView
. I'm using the lastfm-java library that Last.fm recommends using. The method you call to fetch an artists image is getImageURL(ImageSize size)
, but before you do this, you need to tell it which artist you want to reference with a String
parameter. So, in full it would be something like this:
@Override
protected String doInBackground(Object... arg0) {
Artist artist = Artist.getInfo(artistOrMbid, LASTFM_API_KEY);
return artist.getImageURL(ImageSize.EXTRALARGE);
}
Getting all the artists that are on my phone isn't a problem, you just reference MediaStore
. You would do something like this:
private void getArtists() {
String[] projection = new String[] {
MediaStore.Audio.Artists._ID, MediaStore.Audio.Artists.ARTIST,
};
String sortOrder = MediaStore.Audio.Artists.DEFAULT_SORT_ORDER;
Cursor c = getActivity().getContentResolver().query(
MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, projection, null, null, sortOrder);
if (c != null) {
int count = c.getCount();
if (count > 0) {
final int ARTIST_IDX = c.getColumnIndex(MediaStore.Audio.Artists.ARTIST);
for (int i = 0; i < count; i++) {
c.moveToPosition(i);
}
}
c.close();
c = null;
}
}
The Adapter
for my GridView
isn't anything special, it simply extends BaseAdapter
.
Note AQuery is a library I'm using that helps cache and load a Bitmap
from a URL.
public class GridViewAdapter extends BaseAdapter {
private final String[] imageURLs;
private final LayoutInflater mInflater;
private final Activity mActivity;
public GridViewAdapter(String[] urls, Activity activity) {
imageURLs = urls;
mActivity = activity;
mInflater = (LayoutInflater)mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return imageURLs.length;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewholder = null;
// Inflate GridView items
if (convertView == null) {
convertView = mInflater.inflate(R.layout.gridview_items, null);
viewholder = new ViewHolder();
viewholder.mImage = (ImageView)convertView.findViewById(R.id.gridview_image);
convertView.setTag(viewholder);
} else {
viewholder = (ViewHolder)convertView.getTag();
}
AQuery aq = new AQuery(convertView);
aq.id(viewholder.mImage).image(imageURLs[position], false, false, 0, 0, null, 0, 0.75f);
return convertView;
}
}
class ViewHolder {
public ImageView mImage;
}
So in full, my AsyncTask
is as follows:
public class LastfmArtistGetImageURL extends AsyncTask<Object, Integer, String[]> implements
Constants {
private static final String tag = LastfmArtistGetImageURL.class.getSimpleName();
private GridViewAdapter mGridAdapter;
// Test
private final String[] imageIds = {
"http://userserve-ak.last.fm/serve/252/71875544.png",
"http://userserve-ak.last.fm/serve/252/6258507.jpg",
"http://userserve-ak.last.fm/serve/252/51274303.png",
"http://userserve-ak.last.fm/serve/252/58672183.png",
"http://userserve-ak.last.fm/serve/252/72029714.png",
"http://userserve-ak.last.fm/serve/252/17666215.jpg",
"http://userserve-ak.last.fm/serve/252/63247381.png",
"http://userserve-ak.last.fm/serve/252/33665463.jpg"
};
private final String artistOrMbid;
private final GridView mGridView;
private final Activity mActivity;
public LastfmArtistGetImageURL(String name, GridView gv, Activity activity) {
artistOrMbid = name;
mGridView = gv;
mActivity = activity;
}
@Override
protected String[] doInBackground(Object... arg0) {
Artist artist = Artist.getInfo(artistOrMbid, LASTFM_API_KEY);
Collection<String> col = new ArrayList<String>();
col.add(artist.getImageURL(ImageSize.EXTRALARGE));
return col.toArray(new String[0]);
}
@Override
protected void onPostExecute(String[] result) {
if (result != null)
mGridAdapter = new GridViewAdapter(imageIds, mActivity);
mGridView.setAdapter(mGridAdapter);
super.onPostExecute(result);
}
}
When I call my AsyncTask
, I call it in my getArtists()
method like this:
new LastfmArtistGetImageURL(c.getString(ARTIST_IDX), mGridView, getActivity())
.execute();
Problem
When I call this, all of the artists images download, but they download one after the other at position 0
of my GridViewAdapter
. In other words, one image loads, then next, and so on all in the first position
when I need them to be placed into each available position
in the GridView
. When I return my test String[]
in my AsyncTask
everything works like it should. All of the images are placed in order in each available space in the GridView
.
Question
My question is, how do I return each artist image I download into my GridView
correctly and why are the images currently only being loaded at the first position
in my GridViewAdapter
?
Edit - Shubhayu's answer
I moved setting my GridViewAdapter
into my getArtists()
method like so. This results in all the images being downloaded (As says LogCat), but only the last one being set in my GridView
.
String[] test = new LastfmArtistGetImageURL(c.getString(ARTIST_IDX),
mGridView, getActivity()).execute().get();
mGridAdapter = new GridViewAdapter(test, getActivity());
mGridView.setAdapter(mGridAdapter);
smoak's answer
This results in only the last artist image (by the default order) being downloaded and applied in my GridView
.
String[] test = {c.getString(ARTIST_IDX)};
new LastfmArtistGetImageURL(test, mGridView, getActivity()).execute();