在编写音乐 app 时,需要用到SD 卡目录下的音乐文件。遍历(递归) SD 卡目录下的所有音乐文件,显示在相应的条目后,点击相应条目后就可以进入播放界面。点击条目时还需要传递参数可以用 Parcelable 实现传参。在前文中也有该 Parcelable 传参的示例。
效果如下:
遍历 SD 卡目录下的文件:
MusicCursorListActivity.java :
package com.crazy.crazymusicplayer;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;
/**
* MediaStore.Audio.Media.EXTERNAL_CONTENT_URI 对应字段
* 歌曲ID:MediaStore.Audio.Media._ID
* 歌曲的名称:MediaStore.Audio.Media.TITLE
* 歌曲的专辑名:MediaStore.Audio.Media.ALBUM
* 歌曲的歌手名:MediaStore.Audio.Media.ARTIST
* 歌曲文件的路径:MediaStore.Audio.Media.DATA
* 歌曲的总播放时长:MediaStore.Audio.Media.DURATION
* 歌曲文件的大小:MediaStore.Audio.Media.SIZE
*
*/
public class MusicCursorListActivity extends Activity {
private ListView mListView;
private FileCursorAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_list_layout);
mListView = (ListView) findViewById(R.id.music_list_view);
/**
* Android自身具有维护媒体库的功能
* 1.系统创建了一个SQLITE数据库存放所有音乐资源
* 2.MediaScaner类负责扫描系统文件,添加音乐资源到数据库 。
* 什么时间执行扫描操作:1.启动手机,2.插入拔出Sdcard时,3.接收到扫描广播时
*/
Cursor cursor = getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.Media.TITLE_KEY);
mAdapter = new FileCursorAdapter(this, cursor);
mListView.setAdapter(mAdapter);
}
public class FileCursorAdapter extends CursorAdapter {
private LayoutInflater layoutInflater;
public FileCursorAdapter(Context context, Cursor c) {
super(context, c, FLAG_AUTO_REQUERY);
layoutInflater = LayoutInflater.from(context);
}
@Override
public void bindView(View view, Context arg1, Cursor cursor) {
TextView titleTxt = (TextView) view.findViewById(R.id.music_title_txt);
TextView articsTxt = (TextView) view.findViewById(R.id.music_artics_txt);
String title = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
titleTxt.setText(title);
articsTxt.setText(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
}
@Override
public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
return layoutInflater.inflate(R.layout.item_music_cursor_layout,null);
}
}
}
列表:
MusicListActivity.java :
package com.crazy.crazymusicplayer;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.io.File;
import java.util.ArrayList;
public class MusicListActivity extends Activity implements OnItemClickListener{
private ListView mListView;
private Handler mHandler = new Handler();
private ArrayList<MusicBean> mMusicList = new ArrayList<>();
private FileAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_music_list_layout);
mListView = (ListView) findViewById(R.id.music_list_view);
mListView.setOnItemClickListener(this);
mAdapter = new FileAdapter(this);
mListView.setAdapter(mAdapter);
new Thread(new Runnable() {
@Override
public void run() {
scanFileList(Environment.getExternalStorageDirectory());
/** ListView刷新必须在UI线程中 通过Handler消息机制发送刷新代码到UI主线程执行 */
mHandler.post(new Runnable() {
@Override
public void run() {
mAdapter.setListData(mMusicList);
}
});
}
}).start();
}
/**
* 扫描Sdcard(外部存储)下所有文件
*/
public void scanFileList(File parentFile) {
File[] listFile = parentFile.listFiles();
int length = listFile.length;
if (listFile != null) {
for (int i = 0; i < length; i++) {
File file = listFile[i];
if (file.isDirectory()) {
scanFileList(file);
} else {
//file://music/p/xx.mp3
if (file.getName().endsWith(".mp3")) {
MusicBean music = new MusicBean();
String fileName = file.getName();
music.setMusicName(fileName.substring(0, fileName.length()-".mp3".length()));
music.setMusicPath(file.getAbsolutePath());
mMusicList.add(music);
}
}
}
}
}
public class FileAdapter extends BaseAdapter {
private ArrayList<MusicBean> list = new ArrayList<>();
private LayoutInflater layoutInflater;
public FileAdapter(Context context) {
layoutInflater = LayoutInflater.from(context);
}
public void setListData(ArrayList<MusicBean> list) {
this.list = list;
notifyDataSetChanged();
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return list.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.item_music_list_layout, null);
}
MusicBean file = (MusicBean) getItem(position);
TextView nameTxt = (TextView) convertView;
nameTxt.setText(file.getMusicName());
return convertView;
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent intent = new Intent(this, MainActivity.class);
intent.putParcelableArrayListExtra("MUSIC_LIST", mMusicList);
intent.putExtra("CURRENT_POSITION", position);
startActivity(intent);
/*MusicBean musicBean = (MusicBean) parent.getAdapter().getItem(position);
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("MUSIC_BEAN",musicBean);
startActivity(intent);*/
}
}
Parcelable.java :
package com.crazy.crazymusicplayer;
import android.os.Parcel;
import android.os.Parcelable;
public class MusicBean implements Parcelable{
private String musicName;
private String musicPath;
public String getMusicName() {
return musicName;
}
public void setMusicName(String musicName) {
this.musicName = musicName;
}
public String getMusicPath() {
return musicPath;
}
public void setMusicPath(String musicPath) {
this.musicPath = musicPath;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(musicName);
dest.writeString(musicPath);
}
/**
* 必须用 public static final 修饰符
* 对象必须用 CREATOR
*/
public static final Creator<MusicBean> CREATOR = new Creator<MusicBean>() {
@Override
public MusicBean createFromParcel(Parcel source) {
String name = source.readString();
String path = source.readString();
MusicBean music = new MusicBean();
music.setMusicName(name);
music.setMusicPath(path);
return music;
}
@Override
public MusicBean[] newArray(int size) {
return new MusicBean[size];
}
};
}
所需的布局文件:
activity_music_list_layout.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/player_bg_bar" >
<ListView
android:id="@+id/music_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
item_music_cursor_layout.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/music_title_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
android:textSize="18sp"
android:text="小明"
android:textColor="@android:color/white" />
<TextView
android:id="@+id/music_artics_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
android:text="明天"
android:textColor="@android:color/holo_blue_dark" />
</LinearLayout>
activity_music_list_layout.xml :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/player_bg_bar" >
<ListView
android:id="@+id/music_list_view"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
</LinearLayout>
item_music_list_layout.xml :
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceListItemSmall"
android:gravity="center_vertical"
android:textColor="@android:color/white"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingRight="?android:attr/listPreferredItemPaddingRight"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
/>