
MediaPlayer是Android自带的一个多媒体播放类,可以播放音视频流或者本地音视频文件。MediaPlayer方法的调用应该在必定的状况下,下图是一个MediaPlayer对象被支持的播放控制操作驱动的声明周期和状况。其中,椭圆代表MediaPlayer可能驻留的状况android 音频播放,弧线表示驱动MediaPlayer在各个状况之间迁移的播放控制操作。这里有两种种类的弧线。由单箭头开始的弧线代表同步方式调用,而以双箭头开头的弧线代表异步方式读取。图片介绍来源于官方文。
详细介绍可借助Android – 多媒体播放之MediaPlayer基础简介了解更多
现在写一个支持本地缓存的网路音频播放器,并添加了激活锁、WiFi锁和音频焦点等功能。
直接借助MediaPlayer获取播放状况有时不够准确,所以自定义ManagedMediaPlayer继承MediaPlayer,拓展MediaPlayer的功能,控制播放状况
public class ManagedMediaPlayer extends MediaPlayer implements MediaPlayer.OnCompletionListener {
public enum Status {
IDLE, INITIALIZED, STARTED, PAUSED, STOPPED, COMPLETED
}
private Status mState;
private OnCompletionListener mOnCompletionListener;
public ManagedMediaPlayer() {
super();
mState = Status.IDLE;
super.setOnCompletionListener(this);
}
@Override
public void reset() {
super.reset();
mState = Status.IDLE;
}
@Override
public void setDataSource(String path) throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
super.setDataSource(path);
mState = Status.INITIALIZED;
}
@Override
public void start() {
super.start();
mState = Status.STARTED;
}
@Override
public void setOnCompletionListener(OnCompletionListener listener) {
this.mOnCompletionListener = listener;
}
@Override
public void onCompletion(MediaPlayer mp) {
mState = Status.COMPLETED;
if (mOnCompletionListener != null) {
mOnCompletionListener.onCompletion(mp);
}
}
@Override
public void stop() throws IllegalStateException {
super.stop();
mState = Status.STOPPED;
}
@Override
public void pause() throws IllegalStateException {
super.pause();
mState = Status.PAUSED;
}
public void setState(Status mState) {
this.mState = mState;
}
public Status getState() {
return mState;
}
public boolean isComplete() {
return mState == Status.COMPLETED;
}
}
app在长时间后台运行时,手机有也许会开启休眠,这是CUP和WiFi可能会停止运行,影响到app的正常运行,所以我们应该加入激活锁和WiFi锁保证我们在后台长时间播放音频的稳定。
初始化时MediaPlayer时使用激活锁并初始化WiFi锁

// 使用唤醒锁
mMediaPlayer.setWakeMode(MyApplication.getContext(), PowerManager.PARTIAL_WAKE_LOCK);
// 初始化wifi锁
WifiManager.WifiLock wifiLock = ((WifiManager) MyApplication.getContext().getApplicationContext().getSystemService(Context.WIFI_SERVICE)).createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
在起初播放的之后启用WiFi锁
// 启用wifi锁
wifiLock.acquire();
在暂定和释放资源的之后关闭WiFi锁
// 关闭wifi锁
if (wifiLock.isHeld()) {
wifiLock.release();
}
Android系统是一个多任务操作系统,因此同一时刻允许许多任务同时工作。但是这对音频类应用来说是个挑战,因为一旦多个音频同时播放的话,很多状况下客户感受会比较的差。当你需要播放音乐以及发送一个通知的之后,你可以去要求获取音频焦点。一旦取得,就可以自由的使用音频输出设备。但是同时它也在时时刻刻的着音频焦点的变化。当音频焦点变化时android 音频播放,你必须去适合的处理你的音频输出。
自定义AudioFocusManager实现音频焦点变化
public class AudioFocusManager implements AudioManager.OnAudioFocusChangeListener{
private static final String TAG = "AudioFocusManager";
private AudioManager audioManager;
private boolean isPausedByFocusLossTransient;
public AudioFocusManager(Context context) {
audioManager = (AudioManager) context.getSystemService(AUDIO_SERVICE);
}
public boolean requestAudioFocus() {
return audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN)
== AudioManager.AUDIOFOCUS_REQUEST_GRANTED;
}
public void abandonAudioFocus() {
audioManager.abandonAudioFocus(this);
}
@Override
public void onAudioFocusChange(int focusChange) {
switch (focusChange) {
// 重新获得焦点
case AudioManager.AUDIOFOCUS_GAIN:
if (isPausedByFocusLossTransient) {
// 通话结束,恢复播放
AudioPlayer.getInstance().resume();
}
// 恢复音量
AudioPlayer.getInstance().getMediaPlayer().setVolume(1f, 1f);
isPausedByFocusLossTransient = false;
Log.d(TAG, "重新获得焦点");
break;
// 永久丢失焦点,如被其他播放器抢占
case AudioManager.AUDIOFOCUS_LOSS:
PlayerService.stopPlayerService();
abandonAudioFocus();
Log.d(TAG, "永久丢失焦点,如被其他播放器抢占");
break;
// 短暂丢失焦点,如来电
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
AudioPlayer.getInstance().pause();
isPausedByFocusLossTransient = true;
Log.d(TAG, "短暂丢失焦点,如来电");
break;
// 瞬间丢失焦点,如通知
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// 音量减小为一半
AudioPlayer.getInstance().getMediaPlayer().setVolume(0.5f, 0.5f);
Log.d(TAG, "瞬间丢失焦点,如通知");
break;
default:
break;
}
}
}

在初始化MediaPlayer时初始化AudioFocusManager
// 初始化音频焦点管理器
AudioFocusManager audioFocusManager = new AudioFocusManager(MyApplication.getContext());
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-120690-1.html
你还和平的了吗