2014-04-19 4 views
1

나는 이것을 며칠 동안 파악하려고 노력했지만 해결책을 찾지 못하는 것 같습니다.
앨범 아트 드로어 블이 ListView에 표시되지 않음 [Android]

도 미디어 스토어 MediaStore에서 앨범 아트 비트 맵을 받고, 그리고 당김으로 변환 한 후, 그것은하지만 결국 이후의 HashMap (문자열, Object)를 사용하여 사용자 지정 목록보기 레이아웃에서 이미지 뷰에 할당한다는 것이다 문제 실제 장치 및 에뮬레이터에서 실행되는 앨범 아트는 표시되지 않습니다.

LogCat 오류가 없습니다. 사용자 지정 목록보기 레이아웃의 ImageView는 앨범 아트를 표시하지 않습니다.

item.put("icon", drawable); 

로 - -

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

때 기본을 도시

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은 그리기 내가 바꾸면 때문에 도시되지하는 이미지를 발생시키는 일이 될 수 있음을 발견했다 앨범 아트.

이 문제의 원인은 무엇입니까?

답변

0

어댑터 구현이 문제의 원인이며 Drawable이 아닙니다. 코드의 두 라인에서 봐 :

  • item.put("icon", drawable)이 -이 당신의 해시 맵

  • item.put("icon", R.drawable.default_albumart)에 그리기 개체를 박 았어요 -이지도에 int 가치를두고 있지만, 맵은 오브젝트와 작동하기 때문에, 그것은 따라서이

을 넣어되기 전에 autoboxed이다, 문제는 어댑터가 드로어 블을 드로어 블의 정수 식별자와 함께 잘 작동하지만 것입니다 그들 자신. 이것은 SimpleAdapter

의 제약 사항입니다.이 문제를 해결하기 위해 사용자 지정 CursorAdapter을 구현하는 것이 좋습니다. 구현은 간단하며 불필요한 목록 작성, 해시 맵 작성, 앱 메모리 낭비 등과 같은 불필요한 단계를 방지 할 수 있습니다.

의견, 행운을 빌어 다른 것을 물어보십시오!

+0

오른쪽 당신이! 또한 어떻게 완료했는지 알기를 원하는 초보자를위한 코드가 포함되어있는 (다른 문제도있었습니다) 답변을 추가하고 있습니다. 큰! –

+0

다행 이네! – Drew

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