相册艺术画在ListView中不显示[Android]

时间:2014-04-19 06:05:24

标签: android android-listview android-drawable mediastore

我一直在努力解决这个问题,但似乎无法找到解决方案。

问题即使从MediaStore获取专辑封面图并将其转换为drawable后,也会通过HashMap(String,Object)将其分配给自定义ListView布局中的ImageView,但最后在实际设备和模拟器上运行后,没有显示专辑封面。

也没有LogCat错误。自定义列表视图布局的ImageView不显示专辑封面。

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});
          }
    }
}

我检测到drawable可能是导致图像无法显示的那个,因为如果我更换 -

item.put("icon", drawable);

with -

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

显示默认的专辑封面。

知道造成这种情况的原因是什么?

2 个答案:

答案 0 :(得分:0)

您的适配器实现导致了问题,而不是Drawable。 看看这两行代码:

  • item.put("icon", drawable) - 这会将Drawable对象放入您的hashmap

  • item.put("icon", R.drawable.default_albumart) - 这会为您的地图添加int值,但由于地图仅适用于对象,因此在放置之前为autoboxed

因此,问题是您的适配器可以使用drawables的整数标识符,但不适用于drawables本身。这些是SimpleAdapter

的约束

要解决此问题,我建议您实施自定义CursorAdapter。它的实现非常简单,并且可以避免不必要的步骤,例如创建不必要的列表,哈希映射等,浪费应用程序内存。

随意在评论中提出任何其他问题,祝你好运!

答案 1 :(得分:0)

答案是由Drew正确给出的,但这是最终如何实施的。以下是更改 -

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();
}

删除了AsyncTask,因为它不再需要了。

@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);
}
}