2012-01-24 39 views
7

Tôi đang sử dụng hình thức mã trang này:Hiển thị tất cả âm nhạc trên thẻ SD

http://z4android.blogspot.com/2011/06/displaying-list-of-music-files-stored.html

Mã này đang làm việc, nhưng không soo tốt. Khi tôi đang cố cuộn xuống, ListView sẽ lặp lại các bài hát trong danh sách.

Tôi đã tìm kiếm một số mã thay thế, nhưng tôi chưa tìm thấy bất kỳ mã nào.

Cảm ơn bạn đã được trợ giúp.

Trả lời

10

Tôi không hoàn toàn chắc chắn chính xác nguyên nhân gây ra sự cố mà bạn đề cập, nhưng hãy thử mã này.

private MediaPlayer mMediaPlayer; 
private String[] mMusicList; 

/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    mMediaPlayer = new MediaPlayer(); 

    ListView mListView = (ListView) findViewById(R.id.listView1); 

    mMusicList = getMusic(); 

    ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(this, 
    android.R.layout.simple_list_item_1, mMusicList); 
    mListView.setAdapter(mAdapter); 

    mListView.setOnItemClickListener(new OnItemClickListener() { 

    @Override 
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
    long arg3) { 
     try { 
     playSong(mMusicList[arg2]); 
     } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
     } catch (IllegalStateException e) { 
     e.printStackTrace(); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     } 
    } 
    }); 
} 

private String[] getMusic() { 
    final Cursor mCursor = managedQuery(
    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
    new String[] { MediaStore.Audio.Media.DISPLAY_NAME }, null, null, 
    "LOWER(" + MediaStore.Audio.Media.TITLE + ") ASC"); 

    int count = mCursor.getCount(); 

    String[] songs = new String[count]; 
    int i = 0; 
    if (mCursor.moveToFirst()) { 
    do { 
     songs[i] = mCursor.getString(0); 
     i++; 
    } while (mCursor.moveToNext()); 
    } 

    mCursor.close(); 

    return songs; 
} 

private void playSong(String path) throws IllegalArgumentException, 
IllegalStateException, IOException { 
    String extStorageDirectory = Environment.getExternalStorageDirectory() 
    .toString(); 

    path = extStorageDirectory + File.separator + path; 

    mMediaPlayer.reset(); 
    mMediaPlayer.setDataSource(path); 
    mMediaPlayer.prepare(); 
    mMediaPlayer.start(); 
} 
+4

Nó gây ra IOException: Chuẩn bị thất bại. status = 0x1 tại dòng mMediaPlayer.prepare(); –

+0

Nhận IOException chuẩn bị trạng thái không thành công = 0x1 !!! –

-1

Mã có lỗi.

getView không có ý nghĩa gì cả. Gc() đang làm gì ở đó ?! Có gì với tất cả các cuộc gọi moveToPosition().

Dưới đây là đoạn code viết lại

 public View getView(int position, View convertView, ViewGroup parent) { 
       TextView tv = null; 
       String id = null; 
       if (convertView == null) { 
        tv = new TextView(getApplicationContext()); 
       } else 
        tv = (TextView) convertView; 

       music_column_index = musiccursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME); 
       id = musiccursor.getString(music_column_index); 
       music_column_index = musiccursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE); 
       id += " Size(KB): " + musiccursor.getString(music_column_index); 

       tv.setText(id); 
       return tv; 
     } 
+1

"mã ở đó" có nghĩa là mã của @ nikos-leonov? – Gabor

+0

Có, mã ở đây đề cập đến mã bởi @Nikos Leonov. Anh ấy đã cập nhật câu trả lời của anh ấy bằng bình đẳng của tôi, vì vậy bây giờ ok: D –

-1

thử mã này

public View getView(int position, View convertView, ViewGroup parent) { 
System.gc(); 
String id = null; 
TextView tv; 
if (convertView == null) { 
tv = new TextView(mContext.getApplicationContext()); 
} else{ 
tv = (TextView) convertView; 
} 
musiccursor.moveToPosition(position); 
music_column_index = musiccursor 
.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME); 
id = musiccursor.getString(music_column_index); 
music_column_index = musiccursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE); 
id += " Size(KB):" + musiccursor.getString(music_column_index); 
tv.setText(id); 
return tv; 
} 
11

Andreas câu trả lời là đúng cách để làm điều này nhưng mã mà không nhận được đường dẫn tập tin tuyệt đối. Điều này làm cho mMediaPlayer.prepare(); ném IOException: Prepare failed. status=0x1.

Đây là đoạn mã để có được những đường dẫn tập tin cùng với tên file:

private String[] mAudioPath; 
private MediaPlayer mMediaPlayer; 
private String[] mMusicList; 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    mMediaPlayer = new MediaPlayer(); 

    ListView mListView = (ListView) findViewById(R.id.listView1); 

    mMusicList = getAudioList(); 

    ArrayAdapter<String> mAdapter = new ArrayAdapter<String>(this, 
    android.R.layout.simple_list_item_1, mMusicList); 
    mListView.setAdapter(mAdapter); 

    mListView.setOnItemClickListener(new OnItemClickListener() { 

    @Override 
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
    long arg3) { 
    try { 
     playSong(mAudioPath[arg2]); 
    } catch (IllegalArgumentException e) { 
     e.printStackTrace(); 
    } catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    } 
    }); 
} 

private String[] getAudioList() { 
    final Cursor mCursor = getContentResolver().query(
      MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
      new String[] { MediaStore.Audio.Media.DISPLAY_NAME, MediaStore.Audio.Media.DATA }, null, null, 
      "LOWER(" + MediaStore.Audio.Media.TITLE + ") ASC"); 

    int count = mCursor.getCount(); 

    String[] songs = new String[count]; 
    String[] mAudioPath = new String[count]; 
    int i = 0; 
    if (mCursor.moveToFirst()) { 
     do { 
      songs[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)); 
      mAudioPath[i] = mCursor.getString(mCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)); 
      i++; 
     } while (mCursor.moveToNext()); 
    } 

    mCursor.close(); 

    return songs; 
} 

Bây giờ chúng ta có đường dẫn tuyệt đối, chúng tôi không cần phải nhận được con đường một lần nữa. Vì vậy:

private void playSong(String path) throws IllegalArgumentException, 
    IllegalStateException, IOException { 

    Log.d("ringtone", "playSong :: " + path); 

    mMediaPlayer.reset(); 
    mMediaPlayer.setDataSource(path);  
//mMediaPlayer.setLooping(true); 
    mMediaPlayer.prepare(); 
    mMediaPlayer.start(); 
} 

Hãy chắc chắn để sử dụng:

playSong(mAudioPath[arg2]); 

thay vì:

playSong(mMusicList[arg2]); 

trong OnItemClickListener listview.

Để có được chỉ tiêu đề của ca khúc (Trông hơn tao nhã hơn so với tên tập tin với phần mở rộng toàn bộ) sử dụng:

`MediaStore.Audio.Media.TITLE` 

thay vì:

`MediaStore.Audio.Media.DISPLAY_NAME` 
+0

Bạn không gọi getAudioList() – Leo

+1

Tôi đã thực hiện chỉnh sửa. Cảm ơn bạn! :) –

+0

Làm cách nào để lấy danh sách tệp dưới một số Thời lượng? –

Các vấn đề liên quan