显示SD卡上的所有音乐

我正在使用这个页面的代码:

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

代码正在工作,但不是很好。 当我试图向下滚动时,ListView不断重复列表中的歌曲。

我一直在寻找一些替代的代码,但我还没有find任何代码。

谢谢你的帮助。

Solutions Collecting From Web of "显示SD卡上的所有音乐"

我不完全确定是什么原因导致你提到的问题,但试试这个代码。

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

安德烈亚斯的答案是正确的方式来做到这一点,但代码没有得到绝对文件path。 这会导致mMediaPlayer.prepare(); 抛出IOException: Prepare failed. status=0x1 IOException: Prepare failed. status=0x1

以下是获取文件path和文件名的代码:

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

现在我们有了绝对path,我们不需要重新获得path。 所以:

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

确保使用:

 playSong(mAudioPath[arg2]); 

代替:

 playSong(mMusicList[arg2]); 

在列表视图OnItemClickListener。

只获取曲目的标题(看起来比带扩展名的整个文件名更优雅)使用:

 `MediaStore.Audio.Media.TITLE` 

代替:

 `MediaStore.Audio.Media.DISPLAY_NAME` 

代码有超级越野车。

getView没有任何意义。 这是什么gc()在那里?! 什么是所有moveToPosition()调用。

这里是重写的代码

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

试试这个代码

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