Android MediaPlayer的生命周期
MediaPlayer的状态转换图也表征了它的生命周期,搞清楚这个图可以帮助我们在使用MediaPlayer时考虑情况更周全,写出的代码也更具健壮性。
MediaPlayer播放器的方法:
方法:create(Context context, Uri uri)
解释:静态方法,通过Uri创建一个多媒体播放器。
方法:create(Context context, int resid)
解释:静态方法,通过资源ID创建一个多媒体播放器
方法:create(Context context, Uri uri, SurfaceHolder holder)
解释:静态方法,通过Uri和指定 SurfaceHolder 【抽象类】 创建一个多媒体播放器
方法: getCurrentPosition()
解释:返回 Int, 得到当前播放位置
方法: getDuration()
解释:返回 Int,得到文件的时间
方法:getVideoHeight()
解释:返回 Int ,得到视频的高度
方法:getVideoWidth()
解释:返回 Int,得到视频的宽度
方法:isLooping()
解释:返回 boolean ,是否循环播放
方法:isPlaying()
解释:返回 boolean,是否正在播放
方法:pause()
解释:无返回值 ,暂停
方法:prepare()
解释:无返回值,准备同步
方法:prepareAsync()
解释:无返回值,准备异步
方法:release()
解释:无返回值,释放 MediaPlayer 对象
方法:reset()
解释:无返回值,重置 MediaPlayer 对象
方法:seekTo(int msec)
解释:无返回值,指定播放的位置(以毫秒为单位的时间)
方法:setAudioStreamType(int streamtype)
解释:无返回值,指定流媒体的类型
方法:setDataSource(String path)
解释:无返回值,设置多媒体数据来源【根据 路径】
方法:setDataSource(FileDescriptor fd, long offset, long length)
解释:无返回值,设置多媒体数据来源【根据 FileDescriptor】
方法:setDataSource(FileDescriptor fd)
解释:无返回值,设置多媒体数据来源【根据 FileDescriptor】
方法:setDataSource(Context context, Uri uri)
解释:无返回值,设置多媒体数据来源【根据 Uri】
方法:setDisplay(SurfaceHolder sh)
解释:无返回值,设置用 SurfaceHolder 来显示多媒体
方法:setLooping(boolean looping)
解释:无返回值,设置是否循环播放
事件:setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)
解释:监听事件,网络流媒体的缓冲监听
事件:setOnCompletionListener(MediaPlayer.OnCompletionListener listener)
解释:监听事件,网络流媒体播放结束监听
事件:setOnErrorListener(MediaPlayer.OnErrorListener listener)
解释:监听事件,设置错误信息监听
事件:setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener)
解释:监听事件,视频尺寸监听
方法:setScreenOnWhilePlaying(boolean screenOn)
解释:无返回值,设置是否使用 SurfaceHolder 显示
方法:setVolume(float leftVolume, float rightVolume)
解释:无返回值,设置音量
方法:start()
解释:无返回值,开始播放
方法:stop()
解释:无返回值,停止播放
一个简单的MediaPlayer播放器实现:
歌曲信息:PlayInfo.java
import java.util.ArrayList;
import java.util.List;
public class PlayerInfo {
public static final int PLAY = 1; //播放
public static final int BACK = 2; //回退
public static final int PAUSE = 3; //暂停
public static final int NEXT = 4; //下一曲
public static final int STOP = 5; //停止
public static List<String> songs = new ArrayList<String>(); //歌曲列表
public static List<String> getSongs() {
return songs;
}
}
提供歌曲播放的服务:MusicPlayService.java
import java.io.File;
import java.io.IOException;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Environment;
import android.os.IBinder;
import com.example.androidday23_musicplayer.service.constance.PlayerInfo;
public class MusicPlayService extends Service {
private MediaPlayer player;
private int songId;
ProgressThread pt;
private ServiceBroadcastReceiver sbReceiver;
private boolean isStop = false;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int flag = intent.getIntExtra("goodwill", -1);
switch (flag) {
case PlayerInfo.PLAY:
songId = intent.getIntExtra("song", -1);
playMusic(songId);
break;
case PlayerInfo.STOP:
if (player != null) {
player.stop();
player.release();
isStop = true;
}
break;
case PlayerInfo.NEXT:
nextSongs();
break;
case PlayerInfo.PAUSE:
if (player != null) {
if (player.isPlaying()) {
player.pause();
} else {
new Thread(pt).start();
player.start();
}
}
break;
case PlayerInfo.BACK:
if (--songId < 0) {
songId = PlayerInfo.getSongs().size() - 1;
}
playMusic(songId);
break;
default:
break;
}
return super.onStartCommand(intent, flags, startId);
}
private void nextSongs() {
if (++songId >= PlayerInfo.getSongs().size()) {
songId = 0;
}
playMusic(songId);
}
private void playMusic(int songId) {
player.reset();
String path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MUSIC).getAbsolutePath()
+ File.separator + PlayerInfo.getSongs().get(songId);
try {
player.setDataSource(path);
player.prepare();
player.start();
new Thread(pt).start();// 先获取当前时间
Intent intent = new Intent();
intent.setAction("DURATION");
intent.putExtra("duration", player.getDuration());
sendBroadcast(intent);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
class ProgressThread extends Thread {
@Override
public void run() {
super.run();
while (!isStop&&player.isPlaying()) {
Intent intent = new Intent();
intent.setAction("CURRENT");
intent.putExtra("current", player.getCurrentPosition());
// 每次都把当前的进度传给用户,
sendBroadcast(intent);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onCreate() {
player = new MediaPlayer();
player.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
nextSongs();
}
});
pt = new ProgressThread();
sbReceiver = new ServiceBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("seekBarChanged");
registerReceiver(sbReceiver, filter);
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(sbReceiver);
}
class ServiceBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int get = intent.getIntExtra("seekbar", -1); // 获取用户拖动的进度值,让歌曲跳到此进度值
player.seekTo(get);
}
}
}
主界面:MusicPlayActivity.java
import java.io.File;
import java.text.SimpleDateFormat;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import com.example.androidday23_musicplayer.service.MusicPlayService;
import com.example.androidday23_musicplayer.service.constance.PlayerInfo;
public class MusicPlayerActivity extends Activity {
private ListView lv;
private TextView currentTime;
private TextView totalTime;
private SeekBar seekBar;
private ImageButton btn_pause;
private boolean isplaying = false;
private CurrentBroadcastReceiver cReceiver = null;
private DurationBroadcastReceiver dReceiver = null;
private Intent service;
// 读取SD卡中的公共音乐目录
private File mp3Path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
// private File mp3Path = Environment.getExternalStorageDirectory();
@Override
protected void onStart() {
super.onStart();
service = new Intent(this, MusicPlayService.class);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);// 无标题
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);// 全屏
setContentView(R.layout.activity_music_player);
findView();
if (PlayerInfo.getSongs().isEmpty()) {
getMp3List(mp3Path);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, PlayerInfo.getSongs());
lv.setAdapter(adapter);
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
service.putExtra("song", position);
service.putExtra("goodwill", PlayerInfo.PLAY);
startService(service);
btn_pause.setImageResource(R.drawable.pause);
isplaying = false;
}
});
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
Intent intent = new Intent();
intent.setAction("seekBarChanged");
intent.putExtra("seekbar", seekBar.getProgress());
System.out.println(seekBar.getProgress() + "");
sendBroadcast(intent);
}
}
});
}
@Override
protected void onResume() {
super.onResume();
dReceiver = new DurationBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("DURATION");
// 注册广播
registerReceiver(dReceiver, filter);
cReceiver = new CurrentBroadcastReceiver();
IntentFilter cFilter = new IntentFilter();
cFilter.addAction("CURRENT");
// 注册广播
registerReceiver(cReceiver, cFilter);
}
@Override
protected void onStop() {
super.onStop();
// 注销广播
unregisterReceiver(dReceiver);
unregisterReceiver(cReceiver);
}
// 按键操作处理
public void onBtnClick(View v) {
switch (v.getId()) {
case R.id.back: // 上一曲
service.putExtra("goodwill", PlayerInfo.BACK);
startService(service);
break;
case R.id.begin:// 暂停、播放
service.putExtra("goodwill", PlayerInfo.PAUSE);
startService(service);
if (isplaying) {
btn_pause.setImageResource(R.drawable.pause);
isplaying = false;
} else {
btn_pause.setImageResource(R.drawable.begin);
isplaying = true;
}
break;
case R.id.stop:// 停止
service.putExtra("goodwill", PlayerInfo.STOP);
startService(service);
btn_pause.setImageResource(R.drawable.begin);
stopService(service);
break;
case R.id.next:// 下一曲
service.putExtra("goodwill", PlayerInfo.NEXT);
startService(service);
break;
default:
break;
}
}
// 初始化控件
private void findView() {
lv = (ListView) findViewById(R.id.lv);
currentTime = (TextView) findViewById(R.id.currentTime);
totalTime = (TextView) findViewById(R.id.totalTime);
seekBar = (SeekBar) findViewById(R.id.seekBar);
btn_pause = (ImageButton) findViewById(R.id.begin);
}
// 获取SDCard中的mp3文件
private void getMp3List(File file) {
// 获取SDCard中的文件列表
File[] files = mp3Path.listFiles();
if (files != null) {
for (int i = 0; i < files.length; i++) {
if (files[i].getName().indexOf('.') > 0) {
// 取出SDCard中的后缀名
String endIndex = files[i].getName().substring(
files[i].getName().lastIndexOf('.'));
// 筛选MP3文件
if (endIndex.toLowerCase().equals(".mp3")) {
PlayerInfo.getSongs().add(files[i].getName());
}
}
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 每次退出Activity时清空歌曲列表 ,退出后台时,Service播放下一曲时会出错
//if (!PlayerInfo.getSongs().isEmpty()) {
//PlayerInfo.getSongs().clear();
//}
}
// 接收Service发过来的总时间
class DurationBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int data = intent.getIntExtra("duration", -1);
SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
totalTime.setText(sdf.format(data));
seekBar.setMax(data);
}
}
// 接收Service发过来的当前歌曲进度
class CurrentBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int data = intent.getIntExtra("current", -1);
SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
currentTime.setText(sdf.format(data));
seekBar.setProgress(data);
}
}
}
效果图: