Android 笔记-音乐播放器的几个关键点
来源:互联网 发布:桌面 知乎 编辑:程序博客网 时间:2024/05/17 07:07
1.动态更新SeekBar
以前的思路是MediaPlayer 隔几百ms notify注册了监听的activity,今天发现有更为简单的方式
定义变量
SeekBar mProgressBar = null;//刷新对象 Handler mProgressRefresher;//通过handler刷新界面 private static final int DELAY_MILLIS = 200;//刷新间隔 MediaPlayer mPlayer = null;
OnCreate 变量初始化
mProgressBar = (SeekBar) findViewById(R.id.audio_progress); mProgressRefresher = new Handler(); mPlayer = new MediaPlayer(); mPlayer.setOnPreparedListener(this); mPlayer.setOnCompletionListener(this);
当开始播放歌曲时(一般是调用play方法时)开始更新界面
mProgressRefresher.removeCallbacksAndMessages(null); mProgressBar.setMax(mPlayer.getDuration()); mProgressRefresher.postDelayed(new ProgressRefresher(), DELAY_MILLIS); try { mPlayer.setDataSource(this, uri); mPlayer.prepareAsync(); } catch (IOException e) { Log.d(TAG, "Failed to open file: " + e); finish(); }
核心:递归调用handler 更新界面
private class ProgressRefresher implements Runnable { @Override public void run() { if (mPlayer != null) { int position = mPlayer.getCurrentPosition(); mProgressBar.setProgress(position); } mProgressRefresher.removeCallbacksAndMessages(null); mProgressRefresher.postDelayed(new ProgressRefresher(), DELAY_MILLIS);//此处为核心 } }
2.OnAudioFocusChangeListener 的使用
OnAudioFocusChangeListener简介
OnAudioFocusChangeListener简单来说是当android系统同时有两个应用需要使用AudioManager时,为了处理两个应用的声音播放优先级而存在的.如果不使用OnAudioFocusChangeListener,会导致android 音频系统的混乱,比如会同时有两个应用在播放歌曲,歌曲播放中,有电话过来,通话结束音乐不再播放等等现象.
在其他博客中,这种机制称为AudioFocus竞争机制.当焦点变化时,OnAudioFocusChangeListener会收到AudioManager发出的以下通知
AUDIOFOCUS_GAIN:获得了Audio Focus;
AUDIOFOCUS_LOSS:失去了Audio Focus,并将会持续很长的时间。这里因为可能会停掉很长时间,所以不仅仅要停止Audio的播放,最好直接释放掉Media资源。而因为停止播放Audio的时间会很长,如果程序因为这个原因而失去AudioFocus,最好不要让它再次自动获得AudioFocus而继续播放,不然突然冒出来的声音会让用户感觉莫名其妙,感受很不好。这里直接放弃AudioFocus,当然也不用再侦听远程播放控制【如下面代码的处理】。要再次播放,除非用户再在界面上点击开始播放,才重新初始化Media,进行播放。
AUDIOFOCUS_LOSS_TRANSIENT:暂时失去Audio Focus,并会很快再次获得。必须停止Audio的播放,但是因为可能会很快再次获得AudioFocus,这里可以不释放Media资源;
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:暂时失去AudioFocus,但是可以继续播放,不过要在降低音量。
具体使用
/** * 焦点变化 */ OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() { @Override public void onAudioFocusChange(int focusChange) { Log.d(TAG, "mPlayer: [" + mPlayer + "] ,focusChange: [" + focusChange + "]"); Log.i(TAG, "onAudioFocusChange"); if (mPlayer == null) { mAudioManager.abandonAudioFocus(this); return; } switch (focusChange) { //丢失焦点 case AudioManager.AUDIOFOCUS_LOSS: mPlayer.pause(); break; //Used to indicate a transient loss of audio focus. case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: /** * Used to indicate a transient loss of audio focus where the loser of the audio focus can * lower its output volume if it wants to continue playing (also referred to as "ducking"), as * the new focus owner doesn't require others to be silent. */ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: if (mPlayer.isPlaying()) { mPlayer.pause(); } break; //Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration. //应理解为重新获取焦点 case AudioManager.AUDIOFOCUS_GAIN: if (mPlayer != null) { mPlayer.start(); return; } break; } } };
音乐播放器应该做到使用前申请AudioFocus,使用完毕后释放AudioFocus
使用前申请Focus:(基本在play方法中)
if (AudioManager.AUDIOFOCUS_REQUEST_FAILED == mAudioManager .requestAudioFocus(mAudioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT)) { Log.d(TAG, "start() AUDIOFOCUS_REQUEST_FAILED: " + AudioManager.AUDIOFOCUS_REQUEST_FAILED); return; }
使用完毕后释放Focus:(基本在onDestroy中)
mAudioManager.abandonAudioFocus(mAudioFocusListener);
参考资料:http://blog.csdn.net/thl789/article/details/7422931
好文,通俗易懂
3.拖动Seekbar使MediaPlayer播放指定position的音乐
思路:监听Seekbar
具体实现:
1.定义seek方法
private void seek(int pos){ if(mPlayer != null){ mPlayer.seekTo(pos); } }
2.初始化SeekBar时,设置监听
mProgressBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { @Override public void onStopTrackingTouch(SeekBar seekBar) { // end touch SeekBar } @Override public void onStartTrackingTouch(SeekBar seekBar) { // start touch SeekBar } @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if(fromUser){ seek(progress); } } });
- Android 笔记-音乐播放器的几个关键点
- Android音乐播放器的播放实例
- Android 音乐播放器用到的几个方法解说
- Android 音乐播放器开发笔记
- Android入门笔记之音乐播放器
- Android开发笔记之音乐播放器
- WPF的几个关键点
- removeFromSuperview关键的几个点
- AVPlayer 的几个关键点
- Hbase关键的几个点
- Android上层启动过程的几个关键点
- Android上层启动过程的几个关键点
- 音乐播放器笔记
- android学习笔记---43_音乐播放器,音频采集,音乐播放,使用SoundPool播放音效
- android音乐播放器播放音乐卡
- Android 音乐播放 类似音乐播放器
- android 音乐播放器
- Android 音乐播放器
- ajax实现图片轮番滚动
- [NOIP2017模拟]姓名匹配
- MVP中存在的内存泄漏问题
- cookie、session、token的理解
- golang基础-new_make、recover_panic、append、闭包
- Android 笔记-音乐播放器的几个关键点
- Openshift Origin开发日记 11-20
- opencv应用(python)
- Hilbert曲线简介及生成算法
- 大约瑟夫
- 【1031】求阶乘和
- Jzoj4745 看电影
- bzoj3224: Tyvj 1728 普通平衡树(伸展树)
- Linux系统之文件归档、压缩和传输