MediaPlayerActivity類:
[html]
<span style="font-size:14px;">package com.vince.media;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import android.app.Activity;
import android.app.ProgressDialog;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class MediaPlayerActivity extends Activity implements OnCompletionListener,OnErrorListener,OnSeekBarChangeListener,OnItemClickListener,Runnable{
protected static final int SEARCH_MUSIC_SUCCESS = 0;// 搜索成功標記
private SeekBar seekBar;
private ListView listView;
private ImageButton btnPlay;
private TextView tv_currTime,tv_totalTime,tv_showName;
private List<String> list;
private ProgressDialog pd; // 進度條對話框
private MusicListAdapter ma;// 適配器
private MediaPlayer mp;
private int currIndex = 0;// 表示當前播放的音樂索引
private boolean flag = true;//控制進度條線程標記
// 定義當前播放器的狀態״̬
private static final int IDLE = 0;
private static final int PAUSE = 1;
private static final int START = 2;
private static final int CURR_TIME_VALUE = 1;
private int currState = IDLE; // 當前播放器的狀態
//定義線程池(同時隻能有一個線程運行)
ExecutorService es = Executors.newSingleThreadExecutor();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mediaplayer_layout);
list = new ArrayList<String>();
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
mp.setOnErrorListener(this);
initView();
}
@Override
protected void onDestroy() {
if (mp != null) {
mp.stop();
flag= false;
//釋放資源
mp.release();
}
super.onDestroy();
}
/**
* 初始化UI組件
*/
private void initView() {
btnPlay = (ImageButton) findViewById(R.id.media_play);
seekBar = (SeekBar) findViewById(R.id.seekBar1);
seekBar.setOnSeekBarChangeListener(this);
listView = (ListView) findViewById(R.id.listView1);
listView.setOnItemClickListener(this);
tv_currTime = (TextView) findViewById(R.id.textView1_curr_time);
tv_totalTime = (TextView) findViewById(R.id.textView1_total_time);
tv_showName = (TextView) findViewById(R.id.tv_showName);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
//從xml文件中裝載菜單
getMenuInflater().inflate(R.menu.media_menu, menu);
return super.onCreateOptionsMenu(menu);
}
private Handler hander = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case SEARCH_MUSIC_SUCCESS:
//搜索音樂文件結束時
ma = new MusicListAdapter();
listView.setAdapter(ma);
pd.dismiss();
break;
case CURR_TIME_VALUE:
//設置當前時間
tv_currTime.setText(msg.obj.toString());
break;
default:
break;
}
};
};
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
//搜索本地音樂菜單
case R.id.item1_search:
list.clear();
//是否有外部存儲設備
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
pd = ProgressDialog.show(this, "", "正在搜索音樂文件…", true);
new Thread(new Runnable() {
String[] ext = { ".mp3" };
File file = Environment.getExternalStorageDirectory();
public void run() {
search(file, ext);
hander.sendEmptyMessage(SEARCH_MUSIC_SUCCESS);
}
}).start();
} else {
Toast.makeText(this, "請插入外部存儲設備..", Toast.LENGTH_LONG).show();
}
break;
//清除播放列表菜單
case R.id.item2_clear:
list.clear();
ma.notifyDataSetChanged();
break;
//退出菜單
case R.id.item3_exit:
flag = false;
this.finish();
break;
}
return super.onOptionsItemSelected(item);
}
// 搜索音樂文件
private void search(File file, String[] ext) {
if (file != null) {
if (file.isDirectory()) {
File[] listFile = file.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
search(listFile[i], ext);
}
}
} else {
String filename = file.getAbsolutePath();
for (int i = 0; i < ext.length; i++) {
if (filename.endsWith(ext[i])) {
list.add(filename);
break;
}
}
}
}
}
class MusicListAdapter extends BaseAdapter {
public int getCount() {
return list.size();
}
public Object getItem(int position) {
return list.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = getLayoutInflater().inflate(R.layout.list_item,
null);
}
TextView tv_music_name = (TextView) convertView
.findViewById(R.id.textView1_music_name);
tv_music_name.setText(list.get(position));
return convertView;
}
}
private void play() {
switch (currState) {
case IDLE:
start();
break;
case PAUSE:
mp.pause();
btnPlay.setImageResource(R.drawable.ic_media_play);
currState = START;
break;
case START:
mp.start();
btnPlay.setImageResource(R.drawable.ic_media_pause);
currState = PAUSE;
}
}
//上一首
private void previous() {
if((currIndex-1)>=0){
currIndex–;
start();
}else{
Toast.makeText(this, "當前已經是第一首歌曲瞭", Toast.LENGTH_SHORT).show();
}
}
//下一自首
private void next() {
if(currIndex+1<list.size()){
currIndex++;
start();
}else{
Toast.makeText(this, "當前已經是最後一首歌曲瞭", Toast.LENGTH_SHORT).show();
}
}
//開始播放
private void start() {
if (list.size() > 0 && currIndex < list.size()) {
String SongPath = list.get(currIndex);
mp.reset();
try {
mp.setDataSource(SongPath);
mp.prepare();
mp.start();
initSeekBar();
es.execute(this);
tv_showName.setText(list.get(currIndex));
btnPlay.setImageResource(R.drawable.ic_media_pause);
currState = PAUSE;
} catch (IOException e) {
e.printStackTrace();
}
}else{
Toast.makeText(this, "播放列表為空", Toast.LENGTH_SHORT).show();
}
}
//播放按鈕
public void play(View v){
play();
}
//上一首按鈕
public void previous(View v){
previous();
}
//下一首按鈕
public void next(View v){
next();
}
//監聽器,當當前歌曲播放完時觸發,播放下一首
public void onCompletion(MediaPlayer mp) {
if(list.size()>0){
next();
}else{
Toast.makeText(this, "播放列表為空", Toast.LENGTH_SHORT).show();
}
}
//當播放異常時觸發
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.reset();
return false;
}
//初始化SeekBar
private void initSeekBar(){
seekBar.setMax(mp.getDuration());
seekBar.setProgress(0);
tv_totalTime.setText(toTime(mp.getDuration()));
}
private String toTime(int time){
int minute = time / 1000 / 60;
int s = time / 1000 % 60;
String mm = null;
String ss = null;
if(minute<10)mm = "0" + minute;
else mm = minute + "";
if(s <10)ss = "0" + s;
else ss = "" + s;
return mm + ":" + ss;
}
public void run() {
flag = true;
while(flag){
if(mp.getCurrentPosition()<seekBar.getMax()){
seekBar.setProgress(mp.getCurrentPosition());
Message msg = hander.obtainMessage(CURR_TIME_VALUE, toTime(mp.getCurrentPosition()));
hander.sendMessage(msg);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
flag = false;
}
}
}
//SeekBar監聽器
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
//是否由用戶改變
if(fromUser){
mp.seekTo(progress);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
}
public void onStopTrackingTouch(SeekBar seekBar) {
}
//ListView監聽器
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
currIndex = position;
start();
}
}
</span>
mediaplayer_layout.xml佈局文件:
[html]
<span style="font-size:14px;"><?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" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</ListView>
<TextView
android:id="@+id/tv_showName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" />
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<TextView
android:id="@+id/textView1_curr_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:text="00:00" />
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />
<TextView
android:id="@+id/textView1_total_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="00:00" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="previous"
android:src="@drawable/ic_media_previous" />
<ImageButton
android:id="@+id/media_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="play"
android:src="@drawable/ic_media_play" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="next"
android:src="@drawable/ic_media_next" />
</LinearLayout>
</LinearLayout></span>
media_menu.xml文件:
[html]
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/item1_search"
android:icon="@drawable/ic_menu_search"
android:orderInCategory="100"
android:title="@string/search">
</item>
<item
android:id="@+id/item2_clear"
android:icon="@drawable/ic_menu_delete"
android:orderInCategory="200"
android:title="@string/clear_music_list">
</item>
<item
android:id="@+id/item3_exit"
android:icon="@drawable/ic_menu_close_clear_cancel"
android:orderInCategory="300"
android:title="@string/exit">
</item>
</menu></span>
strings.xml文件:
[html]
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, MediaActivity!</string>
<string name="app_name">Media</string>
<string name="search">搜索本地音樂</string>
<string name="clear_music_list">清除播放列表</string>
<string name="exit">退出</string>
</resources></span>