Отображение всей музыки на SD-карте
Я использую кодовую форму этой страницы:
Http://z4android.blogspot.com/2011/06/displaying-list-of-music-files-stored.html
Код работает, но не очень хорошо. Когда я пытаюсь прокрутить вниз, ListView продолжает повторять песни в списке.
Я искал какой-нибудь альтернативный код, но не нашел ни одного.
Спасибо за любую помощь.
4 ответа:
Я не совсем уверен, что именно вызывает проблемы, о которых вы упомянули, но попробуйте этот код.
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(); }
Ответ Андреаса-это правильный способ сделать это, но этот код не получает абсолютный путь к файлу. Это заставляет
mMediaPlayer.prepare();
бросатьIOException: Prepare failed. status=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; }
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]);
В listview OnItemClickListener.
Чтобы получить только название трека (выглядит более элегантно чем все имя файла с расширением) использовать:
`MediaStore.Audio.Media.TITLE`
Вместо:
`MediaStore.Audio.Media.DISPLAY_NAME`
Код там супер-багги.
В
getView
нет никакого смысла. Что там делает этот gc ()?! Что с вызовами all 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; }