Android 学习笔记二十一之 MediaPlayer

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);
}
}
 
}
 


效果图:

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值