1

I have been trying to figure this out for days, but can't seem to find the solution.

The problem is that even after getting the album art bitmap from MediaStore, and converting it to a drawable, it is assigned to an ImageView in a custom ListView layout via HashMap (String, Object), but finally after running on actual device and emulator, no album art is shown.

No LogCat error either. The ImageView of the custom listview layout does not show the album art.

public class AllSongs extends Fragment
{ 
Bitmap bitmap = null;
BitmapDrawable drawable = null; 
private ArrayList<HashMap<String,Object>> list = new ArrayList<HashMap<String,Object>>();
private HashMap<String, Object> item;
private SimpleAdapter sa;
private ListView listview;
 ... 
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
...
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute("500");
}
private class AsyncTaskRunner extends AsyncTask<String, String, String>
    {

    @Override
    protected String doInBackground(String... params) {
        getAllMusicFiles();
        return "Done!";
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        listview.setAdapter(sa); //Set all the file in the list.
    }
    }
private void getAllMusicFiles() {
    // TODO Auto-generated method stub
    //Some audio may be explicitly marked as not being music
    String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

    String[] projection = {
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.ARTIST,
        MediaStore.Audio.Media.ALBUM,
        MediaStore.Audio.Media.ALBUM_ID
    };
    Cursor cursor = getActivity().getApplicationContext().getContentResolver().query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        null,
        null);
    while(cursor.moveToNext()){
          item = new HashMap<String,Object>();
          String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
          String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
          String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
          long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

          final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
            Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
            ContentResolver res = context.getContentResolver();
              InputStream in;
                try { // Yes, the album art has been found. I am sure of this.
                    if(bitmap != null)
                    {
                        bitmap.recycle();
                        bitmap = null;
                        if(drawable != null)
                        {
                            drawable = null;
                        }
                    }
                    in = res.openInputStream(albumArtUri);
                    bitmap = BitmapFactory.decodeStream(in);
                    drawable = new BitmapDrawable(getResources(), bitmap);
                } catch (FileNotFoundException e) { // Album not found so set default album art
                    e.printStackTrace();
                    drawable = (BitmapDrawable) getActivity().getResources().getDrawable(R.drawable.default_albumart);
                }
          item.put("icon", drawable);
          item.put("title", title);
          item.put("artist", artist);
          list.add(item);
          if(cursor.isLast())
          {
             sa = new SimpleAdapter(getActivity(), list,
             R.layout.custom_listview_layout,
                new String[] {"icon", "title","artist" },
                new int[] {R.id.icon,R.id.title, R.id.artist});
          }
    }
}

I have detected that the drawable may be the one causing the image to not be shown because if I replace -

item.put("icon", drawable);

with -

item.put("icon", R.drawable.default_albumart);

it shows the default album art.

Any idea what's causing this?

Advait Saravade
  • 3,029
  • 29
  • 34

2 Answers2

0

It's your adapter implementation is causing the problems, not the Drawable. Look at these two lines of code:

  • item.put("icon", drawable) - this puts a Drawable object to your hashmap

  • item.put("icon", R.drawable.default_albumart) - this puts an int value to your map, but as map only works with objects, it is autoboxed before being put there

Thus, the problem is that your adapter works fine with integer identifiers of drawables, but not the drawables themselves. These are the constraints of SimpleAdapter

To solve this issue I would suggest you to implement your custom CursorAdapter. Its implementation is simply straightforward, and will save you from unnecessary steps, such as creating unnecessary lists, hashmaps etc, wasting app memory.

Feel free to ask anything else in comments, good luck!

Drew
  • 3,307
  • 22
  • 33
  • Right you are! I am also adding an answer to how I achieved this (there were some other issues as well) which will include code for any newbies who want to know how its done. Great! – Advait Saravade Apr 20 '14 at 09:28
0

The answer was given correctly by Drew but here is how it was finally implemented. Here are the changes -

private void getAllMusicFiles() {
    // TODO Auto-generated method stub
    //Some audio may be explicitly marked as not being music
    String selection = MediaStore.Audio.Media.IS_MUSIC + " != 0";

    String[] projection = {
        MediaStore.Audio.Media._ID, // this is required acc to documentation
        MediaStore.Audio.Media.TITLE,
        MediaStore.Audio.Media.ARTIST,
        MediaStore.Audio.Media.ALBUM,
        MediaStore.Audio.Media.ALBUM_ID
    };
    cursor = getActivity().getApplicationContext().getContentResolver().query(
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        null,
        null);
    getActivity().startManagingCursor(cursor);
    listview.setAdapter(new CustomCursorAdapter(context, cursor));
}

@Override
public void onDestroy() {
    // TODO Auto-generated method stub
    if(cursor != null)
    {
    getActivity().stopManagingCursor(cursor);
    cursor.close();
    }
    super.onDestroy();
}

removed the AsyncTask as it wasn't here required anymore.

@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
...
AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute("500");
}



CustomCursorAdapter.java -

public class CustomCursorAdapter extends CursorAdapter {
@SuppressWarnings("deprecation")
public CustomCursorAdapter(Context context, Cursor c) {
    super(context, c);
    // TODO Auto-generated constructor stub
}

private Bitmap bitmap = null;
private BitmapDrawable drawable = null;



@Override
public void bindView(View view, Context context, Cursor cursor) {
    // TODO Auto-generated method stub
    TextView title1 = (TextView) view.findViewById(R.id.title);
    TextView artist1 = (TextView) view.findViewById(R.id.artist);
    ImageView album1 = (ImageView) view.findViewById(R.id.icon);

    String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
    String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
    String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
    long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
      StringBuilder titleBuild = new StringBuilder();
      titleBuild.append(title);
      if(titleBuild.length() > 35)
      {
      titleBuild.setLength(32);
      title = titleBuild.toString()+"...";
      }
      else
      {
          title = titleBuild.toString();
      }
      StringBuilder artistBuild = new StringBuilder();
      artistBuild.append(artist);
      if(artistBuild.length() > 35)
      {
      artistBuild.setLength(32);
      artist = artistBuild.toString()+"...";
      }
      else
      {
      artist = artistBuild.toString();
      }

      final Uri ART_CONTENT_URI = Uri.parse("content://media/external/audio/albumart");
        Uri albumArtUri = ContentUris.withAppendedId(ART_CONTENT_URI, albumId);
        ContentResolver res = context.getContentResolver();
          InputStream in;
            try {
                if(bitmap != null)
                {
                    bitmap = null;
                    if(drawable != null)
                    {
                        drawable = null;
                    }
                }
                in = res.openInputStream(albumArtUri);
                bitmap = BitmapFactory.decodeStream(in);
                // bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), albumArtUri);
                drawable = new BitmapDrawable(context.getResources(), bitmap);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                drawable = (BitmapDrawable) context.getResources().getDrawable(R.drawable.default_albumart);
            }
album1.setImageDrawable(drawable);
title1.setText(title);
artist1.setText(artist);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    // TODO Auto-generated method stub
    LayoutInflater inflater = (LayoutInflater)context.getSystemService
              (Context.LAYOUT_INFLATER_SERVICE);
    return inflater.inflate(R.layout.custom_listview_layout, parent, false);
}
}
Advait Saravade
  • 3,029
  • 29
  • 34