android开发之MediaPlayer+Service MP3播放器

时间:2022-12-30 05:53:28
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.List;

import android.app.ListActivity;
import android.apps.service.PlayerService;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Toast;

public class TestMediaPlayer extends ListActivity {
	/* 前段时间刚学习Android时就觉得MediaPlayer是个很神奇的东西,就试着做了个简单的音乐播放器。
	 * 支持后台播放、进度条拖放、音量控制、读取sdCard音乐文件进行播放等。
	 * */
	private Button playButton = null;
	private Button mFrontButton = null;
	private Button mLastButton = null;
	private Button exit = null;
	/* 声明音量管理器 */
	private AudioManager mAudioManager = null;

	/* 定义进度条 */
	public static SeekBar audioSeekBar = null;

	/* 定义音量大小 */
	private SeekBar audioVolume = null;

	/* 定于一个数据播放列表,用来存放从指定文件中搜索到的文件 */
	public static List<String> mMusicList = new ArrayList<String>();

	/* 定义音乐存放路径 */
//	private static final String MUSIC_PATH = new String("/mnt/sdcard/"); //android 2.2
	private static final String MUSIC_PATH = new String("/sdcard/");//android 2.1
	/* 定义在播放列表中的当前选择项 */
	public static int currentListItme = 0;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		/* 更新列表 */
		musicList();
		/* 得到控件 */
		playButton = (Button) findViewById(R.id.StartMusic);
		mFrontButton = (Button) findViewById(R.id.FrontButton);
		mLastButton = (Button) findViewById(R.id.LastMusic);
		audioVolume = (SeekBar) findViewById(R.id.audioVolume);
		exit = (Button)findViewById(R.id.exit);
		audioSeekBar = (SeekBar) findViewById(R.id.seekbar01);
		/* 播放、暂停监听 */
		playButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				playMusic(AppConstant.PlayerMag.PAUSE);
			}
		});
		/* 监听下一首 */
		mFrontButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				nextMusic();
			}
		});
		/* 监听上一首 */
		mLastButton.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				FrontMusic();
			}
		});
		/*退出监听*/
		exit.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent();
				intent.setClass(TestMediaPlayer.this, PlayerService.class);
				stopService(intent);//停止Service
				try {
					TestMediaPlayer.this.finish();//关闭当前Activity
				} catch (Throwable e) {
					e.printStackTrace();
				}
			
				
			}
		});
		/* 播放进度监听 */
		audioSeekBar.setOnSeekBarChangeListener(new SeekBarChangeEvent());
		/*退出后再次进去程序时,进度条保持持续更新*/
		if(PlayerService.mMediaPlayer!=null){
			//设置进度条最大值
			TestMediaPlayer.audioSeekBar.setMax(PlayerService.mMediaPlayer.getDuration());
			audioSeekBar.setProgress(PlayerService.mMediaPlayer.getCurrentPosition());
		}
		
		
		/* 得到当前音量对象 */
		mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
		/* 把当前音量值赋给进度条 */
		audioVolume.setProgress(mAudioManager
				.getStreamVolume(AudioManager.STREAM_MUSIC));
		/* 监听音量 */
		audioVolume.setOnSeekBarChangeListener(new AudioVolumeChangeEvent());
	}

	public void playMusic(int action) {
		Intent intent = new Intent();
		intent.putExtra("MSG", action);
		intent.setClass(TestMediaPlayer.this, PlayerService.class);
		
		/* 启动service service要在AndroidManifest.xml注册如:<service></service>*/
		
		startService(intent);
	}

	/* 检测sdcard MP3文件并加入到List列表 */
	public void musicList() {
		// 先清除list中的缓存
		mMusicList.clear();
		/* 从指定的路径中读取文件,并与播放列表关联 */
		File home = new File(MUSIC_PATH);
		
		System.out.println(home.canRead());
		/* 读取指定类型的文件,在本程序,指定播放类型为mp3 */
		if (home.listFiles(new MusicFilter()).length > 0) {
			/* 读取文件 */
			for (File file : home.listFiles(new MusicFilter())) {
				mMusicList.add(file.getName());
			}
			/* 播放文件与播放列表关联 */
			ArrayAdapter<String> musicList = new ArrayAdapter<String>(
					TestMediaPlayer.this, R.layout.musictime, mMusicList);
			setListAdapter(musicList);
		}
	}

	/* 音量监听 */
	class AudioVolumeChangeEvent implements SeekBar.OnSeekBarChangeListener {

		@Override
		public void onProgressChanged(SeekBar seekBar, int progress,
				boolean fromUser) {

			// mAudioManager.adjustVolume(AudioManager.ADJUST_LOWER, 0);
			mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress,
					0);

		}

		@Override
		public void onStartTrackingTouch(SeekBar seekBar) {
		}

		@Override
		public void onStopTrackingTouch(SeekBar seekBar) {
		}

	}

	/* 音乐选择监听 */
	@Override
	protected void onListItemClick(android.widget.ListView l, View v,
			int position, long id) {
		super.onListItemClick(l, v, position, id);
		currentListItme = position;
		playMusic(AppConstant.PlayerMag.PLAY_MAG);
	}

	/* 播放下一首 */
	private void nextMusic() {
		if (++currentListItme >= mMusicList.size()) {
			Toast.makeText(TestMediaPlayer.this, "已到最后一首歌曲", Toast.LENGTH_SHORT)
					.show();
			currentListItme = mMusicList.size() - 1;
		} else {
			playMusic(AppConstant.PlayerMag.PLAY_MAG);
		}
	}

	/* 播放上一首歌曲 */
	private void FrontMusic() {
		if (--currentListItme >= 0) {
			playMusic(AppConstant.PlayerMag.PLAY_MAG);

		} else {
			Toast.makeText(TestMediaPlayer.this, "已到第一首歌曲", Toast.LENGTH_SHORT)
					.show();
			currentListItme = 0;
		}
	}
}

/* 播放文件选择类 */
class MusicFilter implements FilenameFilter {
	public boolean accept(File dir, String name) {
		/* 指定扩展名类型 ,可以加其他的音乐格式*/
		return (name.endsWith(".mp3"));
	}
}

/* 拖放进度监听 ,别忘了Service里面还有个进度条刷新*/
class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {

	@Override
	public void onProgressChanged(SeekBar seekBar, int progress,
			boolean fromUser) {
		/*假设改变源于用户拖动*/
		if (fromUser) {
			PlayerService.mMediaPlayer.seekTo(progress);// 当进度条的值改变时,音乐播放器从新的位置开始播放
		}
	}

	@Override
	public void onStartTrackingTouch(SeekBar seekBar) {
		PlayerService.mMediaPlayer.pause(); // 开始拖动进度条时,音乐暂停播放
	}

	@Override
	public void onStopTrackingTouch(SeekBar seekBar) {
		PlayerService.mMediaPlayer.start(); // 停止拖动进度条时,音乐开始播放
	}
}


service类

首先建议不要把播放音乐放在Activity中,因为关闭Activity后就不能实现后台播放。所以播放音乐要放在Service中,我们只需要管理ActivityService间的通信就好了。下面就是个Service类。直接看注释和代码:

package android.apps.service;

import java.io.IOException;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.IBinder;
import android.widget.Toast;

import android.apps.*;

public class PlayerService extends Service implements Runnable,
		MediaPlayer.OnCompletionListener {
	/* 定于一个多媒体对象 */
	public static MediaPlayer mMediaPlayer = null;
	// 是否单曲循环
	private static boolean isLoop = false;
	// 用户操作
	private int MSG;

	/* 定义要播放的文件夹路径 */
	private static final String MUSIC_PATH = new String("/sdcard/");

	@Override
	public IBinder onBind(Intent intent) {
		return null;// 这里的绑定没的用,上篇我贴出了如何将activity与service绑定的代码
	}

	@Override
	public void onCreate() {
		super.onCreate();
		if (mMediaPlayer != null) {
			mMediaPlayer.reset();
			mMediaPlayer.release();
			mMediaPlayer = null;
		}
		mMediaPlayer = new MediaPlayer();
		/* 监听播放是否完成 */
		mMediaPlayer.setOnCompletionListener(this);
	}

	@Override
	public void onDestroy() {
		super.onDestroy();

		if (mMediaPlayer != null) {
			mMediaPlayer.stop();
			mMediaPlayer.release();
			mMediaPlayer = null;
		}

		System.out.println("service onDestroy");
	}
    /*启动service时执行的方法*/
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		/*得到从startService传来的动作,后是默认参数,这里是我自定义的常量*/
		MSG = intent.getIntExtra("MSG", AppConstant.PlayerMag.PLAY_MAG);
		if (MSG == AppConstant.PlayerMag.PLAY_MAG) {
			playMusic();
		}
		if (MSG == AppConstant.PlayerMag.PAUSE) {
			if (mMediaPlayer.isPlaying()) {// 正在播放
				mMediaPlayer.pause();// 暂停
			} else {// 没有播放
				mMediaPlayer.start();
			}
		}

		return super.onStartCommand(intent, flags, startId);
	}

	@SuppressWarnings("static-access")
	public void playMusic() {
		try {
			/* 重置多媒体 */
			mMediaPlayer.reset();
			/* 读取mp3文件 */
			mMediaPlayer.setDataSource(MUSIC_PATH+TestMediaPlayer.mMusicList.get(TestMediaPlayer.currentListItme));
//			Uri uri = Uri.parse(MUSIC_PATH+TestMediaPlayer.mMusicList.get(TestMediaPlayer.currentListItme));
//			
//			mMediaPlayer.create(PlayerService.this,uri);
			/* 准备播放 */
			mMediaPlayer.prepare();
			/* 开始播放 */
			mMediaPlayer.start();
			/* 是否单曲循环 */
			mMediaPlayer.setLooping(isLoop);
			// 设置进度条最大值
			TestMediaPlayer.audioSeekBar.setMax(PlayerService.mMediaPlayer
					.getDuration());
			new Thread(this).start();
		} catch (IOException e) {
		}

	}

	// 刷新进度条
	@Override
	public void run() {
		int CurrentPosition = 0;// 设置默认进度条当前位置
		int total = mMediaPlayer.getDuration();//
		while (mMediaPlayer != null && CurrentPosition < total) {
			try {
				Thread.sleep(1000);
				if (mMediaPlayer != null) {
					CurrentPosition = mMediaPlayer.getCurrentPosition();
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			TestMediaPlayer.audioSeekBar.setProgress(CurrentPosition);
		}

	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		/* 播放完当前歌曲,自动播放下一首 */

		if (++TestMediaPlayer.currentListItme >= TestMediaPlayer.mMusicList
				.size()) {
			Toast.makeText(PlayerService.this, "已到最后一首歌曲", Toast.LENGTH_SHORT)
					.show();
			TestMediaPlayer.currentListItme--;
			TestMediaPlayer.audioSeekBar.setMax(0);
		} else {
			playMusic();
		}
	}
}

参数封装

/**
 * @把参数这样封装易于管理和阅读
 *
 */
public interface AppConstant {
	public class PlayerMag{
		public static final int PLAY_MAG=1;//开始播放
		public static final int PAUSE=2;//暂停播放
	}
}


详细代码下载http://download.csdn.net/source/3318587