Android 在SD卡上显示所有音乐

Android 在SD卡上显示所有音乐,android,listview,sd-card,Android,Listview,Sd Card,我正在使用此页面中的代码: 代码正在运行,但不是很好。 当我试图向下滚动时,ListView会不断重复列表中的歌曲 我一直在寻找一些替代代码,但我没有找到任何 谢谢您的帮助。我不完全确定您提到的问题的确切原因,但请尝试以下代码 private MediaPlayer mMediaPlayer; private String[] mMusicList; /** Called when the activity is first created. */ @Override public void

我正在使用此页面中的代码:

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

我一直在寻找一些替代代码,但我没有找到任何


谢谢您的帮助。

我不完全确定您提到的问题的确切原因,但请尝试以下代码

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();
}
私有媒体播放器层;
私有字符串[]mMusicList;
/**在首次创建活动时调用*/
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMediaPlayer=新媒体播放器();
ListView mListView=(ListView)findViewById(R.id.listView1);
mMusicList=getMusic();
ArrayAdapter mAdapter=新的ArrayAdapter(此,
android.R.layout.simple_list_item_1,mMusicList);
mListView.setAdapter(mAdapter);
setOnItemClickListener(新的OnItemClickListener(){
@凌驾
公共链接(AdapterView arg0、视图arg1、内部arg2、,
长arg3){
试一试{
播放歌曲(mMusicList[arg2]);
}捕获(IllegalArgumentException e){
e、 printStackTrace();
}捕获(非法状态){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
});
}
私有字符串[]getMusic(){
最终光标mCursor=managedQuery(
MediaStore.Audio.Media.EXTERNAL\u CONTENT\u URI,
新字符串[]{MediaStore.Audio.Media.DISPLAY_NAME},null,null,
“下(“+MediaStore.Audio.Media.TITLE+”)ASC”);
int count=mCursor.getCount();
字符串[]歌曲=新字符串[计数];
int i=0;
if(mCursor.moveToFirst()){
做{
songs[i]=mCursor.getString(0);
i++;
}while(mCursor.moveToNext());
}
mCursor.close();
返回歌曲;
}
私有void playSong(字符串路径)抛出IllegalArgumentException,
IlegalStateException,IOException{
字符串extStorageDirectory=Environment.getExternalStorageDirectory()
.toString();
path=extStorageDirectory+File.separator+path;
mmediplayer.reset();
mmediplayer.setDataSource(路径);
mmediplayer.prepare();
mmediplayer.start();
}

那里的代码有超级错误

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

Andreas answer是这样做的正确方法,但该代码没有获得绝对文件路径。 这会导致
mmediplayer.prepare()引发
IOException:准备失败。状态=0x1

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

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;
}
确保使用:

playSong(mAudioPath[arg2]);
而不是:

playSong(mMusicList[arg2]);
`MediaStore.Audio.Media.DISPLAY_NAME`
在listview中,单击Listener

要仅获取曲目的标题(看起来比扩展名为的整个文件名更优雅),请使用:

而不是:

playSong(mMusicList[arg2]);
`MediaStore.Audio.Media.DISPLAY_NAME`

它导致IOException:准备失败。行mmediplayer.prepare()处的状态=0x1;获取IOException准备失败状态=0x1!!!“那里的代码”是指@nikos leonov的代码?是的,那里的代码是指@nikos leonov的代码。他已将他的答案更新为与我的答案相同,因此现在一切正常:DYou不调用getAudioList(),我已进行了编辑。谢谢!:)如何在短时间内获取文件列表?我尝试了标题1,但它说列标题不存在。如果有任何帮助,我们将不胜感激。为什么您要两次声明String[]songs和String[]mAudioPath?我认为不需要在getAudioList()方法中再次声明它。