主要功能,遍历的SD卡,播放、暂停、上一首、下一首、拖动进度条播放、播放完一首就自动播放下一首,显示当前进度条时间的刷新,每首歌曲总时间的刷新,PopupWindow弹出一个ListView,歌曲名字的后缀名分割,
这儿注意就是:mPopupWindom.setFocusable(true);// 此方法可以保证PopupWindom里面嵌套的ListView有点击响应。
声明各种控件.
private ImageView mUpMusicBtn, mStartAndSuspendMusicBtn, mNextMusicBtn,
mListMusicBtn;
private SeekBar mSeekBar;
private TextView mTitleMusicNameText, mCurrentTimeText, mAllTimeText;
private Handler mHandler = new Handler();// 刷新当前播放时的时间
private MediaPlayer mediaPlay = new MediaPlayer();
String filePath;
private PopupWindow mPopupWindom;
private LayoutInflater mInflater;
//SD卡的目录
private File allFile = Environment.getExternalStorageDirectory();
// 装遍历出来的音乐文件的名字
private List<File> fileName = new ArrayList<File>();
// 装遍历出来的音乐文件的名字,是分割过后的音乐文件名字,没有后缀名
private ArrayList<String> sdcardMusicName = new ArrayList<String>();
// 等于当前点的哪一项, 在上一首和下一首中用到;点击上一首和下一首时也会再次被实例化
private int listMusicChecked;
加载布局和遍历文件、SeekBar拖动的监听等:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_kugou_music);
getFileWithMusic(allFile);// 遍历文件获取音乐文件
example();// 实例化控件
new Thread(new RefrshTime()).start();// 设置进度条的刷新
mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onStopTrackingTouch(SeekBar seekBar) {
// 停止拖动进度条时,音乐开始播放
}
public void onStartTrackingTouch(SeekBar seekBar) {
// 开始拖动进度条时,音乐暂停播放
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// fromUser判断是用户改变的滑块的值,拖动SeekBar的监听并响应
if (fromUser == true) {
mediaPlay.seekTo(progress);
}
}
});
}
封装实例化控件的方法:
/**
* 实例化控件
*/
public void example() {
mUpMusicBtn = (ImageView) findViewById(R.id.copy_kuguo_up_music_btn);
mStartAndSuspendMusicBtn = (ImageView) findViewById(R.id.copy_kuguo_start_and_suspend_music_btn);
mNextMusicBtn = (ImageView) findViewById(R.id.copy_kuguo_next_music_btn);
mListMusicBtn = (ImageView) findViewById(R.id.copy_kugou_list_music_imagebtn);
mTitleMusicNameText = (TextView) findViewById(R.id.title_music_name_text);
mCurrentTimeText = (TextView) findViewById(R.id.copy_kuguo_current_time_text);
mAllTimeText = (TextView) findViewById(R.id.copy_kuguo_all_time_text);
mSeekBar = (SeekBar) findViewById(R.id.copy_kuguo_seekbar);
mInflater = LayoutInflater.from(this);
mUpMusicBtn.setOnClickListener(this);
mStartAndSuspendMusicBtn.setOnClickListener(this);
mNextMusicBtn.setOnClickListener(this);
mListMusicBtn.setOnClickListener(this);
}
播放器的初始化准备阶段方法:
/**
* 播放器里面歌曲的准备阶段
*/
public void musicMediaPlayerPrepare(String s) {
try {
mediaPlay.setDataSource(s);
mediaPlay.prepare();
mediaPlay.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
点击暂停、开始的方法:
/**
* 要恶魔暂停,要么播放
*/
public void startMusic() {
if (!mediaPlay.isPlaying()) {
mStartAndSuspendMusicBtn
.setImageResource(R.drawable.kg_lock_screen_pause_button_pressed);
mediaPlay.start();//播放
} else {
mStartAndSuspendMusicBtn
.setImageResource(R.drawable.kg_lock_screen_play_button_pressed);
mediaPlay.pause();//暂停
}
}
各种控件监听的方法:
/**
* 控件的监听
*/
public void onClick(View v) {
switch (v.getId()) {
case R.id.copy_kuguo_up_music_btn:// 上一首按钮
if (listMusicChecked - 1 < 0) {// 数组从0开始计数
Toast.makeText(this, "已经是第一个了", 0).show();
listMusicChecked = 0;//再一次赋值,更新
} else {
mediaPlay.reset();// 重置
musicMediaPlayerPrepare("File://"
+ fileName.get(listMusicChecked - 1));// 传入歌曲,
// 设置title上面显示的名字
Log.i("11", "名字数组对象:" + sdcardMusicName);
String divicionUpName = musicNameToTitle(sdcardMusicName
.get(listMusicChecked - 1));
mTitleMusicNameText.setText(divicionUpName);//Title处显示当前播放歌曲的名字
listMusicChecked = listMusicChecked - 1;//再一次赋值,更新
}
break;
case R.id.copy_kuguo_start_and_suspend_music_btn:// 暂停,开始按钮
startMusic();
break;
case R.id.copy_kuguo_next_music_btn:// 下一首按钮
if (listMusicChecked + 1 < fileName.size()) {// 数组从0开始计数
mediaPlay.reset();// 重置
musicMediaPlayerPrepare("File://"
+ fileName.get(listMusicChecked + 1));// 传入歌曲,
// 设置title上面显示的名字
String divicionNextName = musicNameToTitle(sdcardMusicName
.get(listMusicChecked + 1));
mTitleMusicNameText.setText(divicionNextName);
listMusicChecked = listMusicChecked + 1;//再一次赋值,更新
} else {
Toast.makeText(this, "已经是最后一个了", 0).show();
listMusicChecked = fileName.size();
}
break;
case R.id.copy_kugou_list_music_imagebtn:
listMusicForPopupWindom();// 弹出音乐列表窗口
break;
}
}
PopupWindow的效果:
/**
* 点击Title最右边的按钮弹出音乐列表窗口,用PopupWindom来实现
*/
public void listMusicForPopupWindom() {
//高度要适当的设置
mPopupWindom = new PopupWindow(getListViewForPopupWindom(), 700, 500);
mPopupWindom.setFocusable(true);// 此方法可以保证PopupWindom里面嵌套的ListView有点击响应
// 下面这三行代码可以让你点击空白处来关闭PopWindow 弹出的窗口
mPopupWindom.setTouchable(true);
mPopupWindom.setOutsideTouchable(true);
mPopupWindom.setBackgroundDrawable(new BitmapDrawable());
// 点击按钮就弹出窗口
mListMusicBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mPopupWindom.isShowing()) {// 判断窗口是否已经弹出弹出
// mPopWind.setOutsideTouchable(false);
mPopupWindom.dismiss();// 关闭窗口
} else {
mPopupWindom.showAsDropDown(v);// 弹出窗口
}
}
});
}
ListView的监听、以及返回PopupWindow所需要的View:
/**
* 把装有ListView的布局返回给PopupWindom的实例化中,才有弹窗的布局类型
*/
public View getListViewForPopupWindom() {
View v = mInflater.inflate(R.layout.copykugou_listview_music_layout,
null);
ListView mListview = (ListView) v
.findViewById(R.id.copykugou_listview_to_musicname);
TextView allMusicPopupText = (TextView) v
.findViewById(R.id.popupwindow_allmusic_to_text);
allMusicPopupText.setText("总共" + fileName.size() + "首歌曲");
ListMusicAdapter listBaseadapter = new ListMusicAdapter(this);
mListview.setAdapter(listBaseadapter);
listBaseadapter.setData(fileName);
// popupWindom弹出的ListView的监听
mListview.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
listMusicChecked = position;// 实例化计数器,用于上一首,下一首
ListMusicAdapter fileBackAdapter = (ListMusicAdapter) parent
.getAdapter();
//获得适配器的每一项
File fileBack = (File) fileBackAdapter.getItem(position);
String backPrepareMusic = fileBack.getPath();
if (mediaPlay.isPlaying()) {
mediaPlay.reset();
}
// 歌曲的地址传过去才能播放
musicMediaPlayerPrepare("file://" + backPrepareMusic);
// title上显示播放歌曲的名字
mTitleMusicNameText.setText(musicNameToTitle(fileBack.getName()));
// 点击PopupWindow后,点击ListView里面的任意一项时,就关闭窗口
mPopupWindom.dismiss();
}
});
return v;
}
遍历mp3文件,递归的运用:
/**
* 无限遍历一个文件夹,找出音乐文件,并添加到List里面,然后设置给适配器
*/
public void getFileWithMusic(File fileAddress) {
if (fileAddress != null) {
File[] fileList = fileAddress.listFiles();
if (fileList != null) {
for (File f : fileList) {
if (f.isDirectory()) {
getFileWithMusic(f);
} else {
String s = f.getName();
if (s.endsWith(".mp3") || s.endsWith(".apk")) {
fileName.add(f);
Log.i("11", "歌曲的名字:" + s);
sdcardMusicName.add(s);
}
}
}
}
}
}
歌曲后缀名的分割,android中需要加[ ] ,用点(.)分割:
/**
* 分割歌曲的后缀名
*/
public String musicNameToTitle(String s) {
// xinyang.mp3
String[] divisionMusicName = s.split("[.]");
return divisionMusicName[0];
}
进度条的刷新以及、时间的刷新、检测播放完自动播放下一首:
/**
* 刷新进度条,Handler在主线程中实例化,刷新当前播放的时间,用TextView来显示当前时间和,总的时间
*/
public class RefrshTime implements Runnable {
public void run() {
while (true) {
if (mediaPlay.isPlaying() && mediaPlay != null) {
mSeekBar.setMax(mediaPlay.getDuration());
mSeekBar.setProgress(mediaPlay.getCurrentPosition());
}
mHandler.post(new Runnable() {
public void run() {
if (mediaPlay != null && !mediaPlay.isPlaying()) {
mAllTimeText.setText("00:00");
mCurrentTimeText.setText("00:00");
} else {
// 设置总的时间
int allTimePoint = (mediaPlay.getDuration() / 1000) / 60;
int allTimeSec = (mediaPlay.getDuration() / 1000) % 60;
if (allTimePoint < 10 && allTimeSec < 10) {
mAllTimeText.setText("0" + allTimePoint + ":"
+ allTimeSec);
} else if (allTimePoint < 10 && allTimeSec >= 10) {
mAllTimeText.setText("0" + allTimePoint + ":"
+ allTimeSec);
} else if (allTimePoint > 10 && allTimeSec < 10) {
mAllTimeText.setText(allTimePoint + ":0"
+ allTimeSec);
} else if (allTimePoint > 10 && allTimeSec >= 10) {
mAllTimeText.setText(allTimePoint + ":0"
+ allTimeSec);
}
// 设置当前的时间
int currentPoint = (mediaPlay.getCurrentPosition() / 1000) / 60;
int currentSec = (mediaPlay.getCurrentPosition() / 1000) % 60;
if (currentPoint < 10 && currentSec < 10) {
mCurrentTimeText.setText("0" + currentPoint
+ ":0" + currentSec);
} else if (currentPoint < 10 && currentSec >= 10) {
mCurrentTimeText.setText("0" + currentPoint
+ ":" + currentSec);
} else if (currentPoint > 10 && currentSec < 10) {
mCurrentTimeText.setText(currentPoint + ":0"
+ currentSec);
} else if (currentPoint > 10 && currentSec >= 10) {
mCurrentTimeText.setText(currentPoint + ":"
+ currentSec);
}
// 自动播放下一首
if (allTimeSec == currentSec) {
if (listMusicChecked + 1 < fileName.size()) {// 数组从0开始计数
mediaPlay.reset();// 重置
musicMediaPlayerPrepare("File://"
+ fileName
.get(listMusicChecked + 1));// 传入歌曲,
// 设置title上面显示的名字
String divicionNextName = musicNameToTitle(sdcardMusicName
.get(listMusicChecked + 1));
mTitleMusicNameText
.setText(divicionNextName);
listMusicChecked = listMusicChecked + 1;
} else {
listMusicChecked = fileName.size();
}
Toast.makeText(CopyKugouMainActivity.this,
"播放下一首", 0).show();
}
}
}
});
try {
// 设置刷新的时间
Thread.sleep(1000 - (mediaPlay.getCurrentPosition() % 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}