最近项目中要增加一些特殊的功能,实现音乐的在线播放。虽说网上源码一大把,demo一大堆,但是能用的其实寥寥无几 ,看来关键时刻还是自己动手,丰衣足食啊。话不多说,直接看效果图吧:
,看来关键时刻还是自己动手,丰衣足食啊。话不多说,直接看效果图吧:
 
看是不是很美观。
该功能主要是实现:从后台请求一个音乐地址,进而实现在线播放,且能够支持暂停,快进,以及播放进度条,播放时间等。
 
代码不是很多,主要是用MediaPlayer重要工具类
这里控制着音乐的播放,暂停,开始播放等播放状态。
 public void play() {new Thread(new Runnable() {@Overridepublic void run() {if (player.mediaPlayer.isPlaying() || getPlayStatus() == PlayStatus.PLAYING) {player.pause();setPlayStatus(PlayStatus.PAUSE);} else if(getPlayStatus() == PlayStatus.NOPLAY || getPlayStatus() == PlayStatus.FINISH){if(getPlayStatus() == PlayStatus.FINISH){player.mediaPlayer.reset();//重置MediaPlayer到初始化状态player.mediaPlayer.seekTo(0);//须将播放时间设置到0;这样才能在下次播放是重新开始,否则会继续上次播放}player.playUrl(URLMUSIC);setPlayStatus(PlayStatus.PLAYING);}else if(getPlayStatus() == PlayStatus.PAUSE){player.start();//继续播放setPlayStatus(PlayStatus.PLAYING);}}}).start();}这里要注意的是:
 player.mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {@Overridepublic void onBufferingUpdate(MediaPlayer mp, int percent) {Long totleLong = new Long((long) player.mediaPlayer.getDuration());Long currentLong = new Long((long) player.mediaPlayer.getCurrentPosition());String totleTime = formatter.format(mp.getDuration());String currentTime = formatter.format((mp.getCurrentPosition()));LogUtil.e(TAG,"totle:  " +totleTime+"当前:  " + currentTime);if(mp.isPlaying()){//减少误差,避免得到getDuration()的时间出问题---->在这里花费了好多的时间mySeekProgressListener.onMySeekProgressData(totleTime,currentTime,0);if(totleTime.equals(currentTime)){//用这样的方式判断完成,减少时间的误差LogUtil.e(TAG,"我进来啦!!!");setPlayStatus(PlayStatus.FINISH);player.mediaPlayer.pause();// player.mediaPlayer.release();}}}});这里的 setOnBufferingUpdateListener是用于音乐或者视频在线缓冲的更新监听器
 public class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {int progress;@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {LogUtil.e(TAG,"totle:  " +player.mediaPlayer.getDuration());this.progress  = progress * player.mediaPlayer.getDuration() / seekBar.getMax();}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {player.mediaPlayer.seekTo(progress);if(getPlayStatus() == PlayStatus.FINISH) {play();}}}这里是坚挺拖动条的拖动状态,用于显示在线音乐的进度,当然是SeekBar能进行拖动。
以下是全部代码:
public class MainActivity extends Activity implements View.OnClickListener{private final int MUSIC_FINISH = 1000;@Bind(R.id.iv_bg_music)ImageView iv_bg_music;@Bind(R.id.titlebar_back_music)ImageView titlebar_back_music;@Bind(R.id.titlebar_title_music)TextView titlebar_title_music;@Bind(R.id.ib_paly_music)//播放音乐ImageButton ib_paly_music;@Bind(R.id.ll_to_play)//播放音乐LinearLayout ll_to_play;@Bind(R.id.tv_time_progress)//正在播放的时间TextView tv_time_progress;@Bind(R.id.tv_time_totle)//播放总时间TextView tv_time_totle;@Bind(R.id.sb_music_progress)//播放拖动条SeekBar sb_music_progress;private MusicPlay mausicPlay;private SimpleDateFormat formatter;private Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case MUSIC_FINISH:tv_time_progress.setText("0:00");//播放完毕后,重新设置没有播放的状态sb_music_progress.setProgress(0);ib_paly_music.setBackgroundResource(R.drawable.iv_paly);break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButterKnife.bind(this);initListener();initView();}private void initView() {formatter = new SimpleDateFormat("mm:ss");formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));mausicPlay = MusicPlay.getInstance(this).setMySeekListener(sb_music_progress).setMySeekProgressListener(new MusicPlay.MySeekProgressListener() {@Overridepublic void onMySeekProgressData(String totleTime, String currentTime,int finishStatus) {if(finishStatus == 100){//播放完毕LogUtil.e("yuyahao","mian 时间 放放完啦!!! ");}else{tv_time_totle.setText(totleTime);if(totleTime.equals(currentTime)){//用时间字符串进行比较,防止出现两次的时间结束状态handler.postDelayed(new Runnable() {@Overridepublic void run() {Message msg = handler.obtainMessage();msg.what = MUSIC_FINISH;handler.sendMessage(msg);}}, 800);}else{tv_time_totle.setText(totleTime);tv_time_progress.setText(currentTime);}}}});ib_paly_music.setTag(R.drawable.iv_stop_paly);ib_paly_music.setBackgroundResource(R.drawable.iv_paly);}private void initListener() {ib_paly_music.setOnClickListener(this);titlebar_back_music.setOnClickListener(this);ll_to_play.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.ll_to_play:case R.id.ib_paly_music://博faNG或者是暂停Integer tag = (Integer) ib_paly_music.getTag();if(mausicPlay.isPlayIng()){//正在播放,去暂停播放ib_paly_music.setBackgroundResource(R.drawable.iv_paly);}else{//去进行播放ib_paly_music.setBackgroundResource(R.drawable.iv_stop_paly);}mausicPlay.play();break;case R.id.titlebar_back_music:onBackPressed();break;}}@Overrideprotected void onDestroy() {super.onDestroy();if(mausicPlay != null){mausicPlay.onDestroy();}}@Overridepublic void onBackPressed() {if(mausicPlay.isPlayIng()){}else{super.onBackPressed();}}
}
工具类:
/*** Created by fei on 2016/11/12.* 音乐在线播放  工具类*/
public class MusicPlay {private static final String TAG = "yyh";private static Player player;private static MusicPlay musicPlay;private String URLMUSIC = "http://abv.cn/music/红豆.mp3";private Context context;private static PlayStatus isPlaystatic  = PlayStatus.NOPLAY;//播放状态:默认0不播放,  1:开始博播放 ,2是暂停播放 ,3:是播放完毕private static SimpleDateFormat formatter;//private  SeekBar sb_music_progress;//当前播放的拖动条public enum  PlayStatus{NOPLAY(0),//默认0不播放PLAYING(1),//,1:开始博播放PAUSE(2),//,2是暂停播放FINISH(3);//3:是播放完毕private int status;PlayStatus(int status) {this.status = status;}public int getStatus() {return status;}public void setStatus(int status) {this.status = status;}}public MusicPlay(Context context) {this.context = context;}public static void  setPlayStatus(PlayStatus isPlaystatic){MusicPlay.isPlaystatic = isPlaystatic;}public PlayStatus getPlayStatus(){return this.isPlaystatic;}public static MusicPlay getInstance(Context context) {if (musicPlay == null) {musicPlay = new MusicPlay(context);formatter = new SimpleDateFormat("mm:ss");formatter.setTimeZone(TimeZone.getTimeZone("GMT+00:00"));}return musicPlay;}public  MusicPlay setMySeekListener(SeekBar sb_music_progress){sb_music_progress.setOnSeekBarChangeListener(new SeekBarChangeEvent());player  = new Player(sb_music_progress);initSetMediaPlaylistener();return musicPlay;}public  MusicPlay setMySeekProgressListener(MySeekProgressListener mySeekProgressListener){this.mySeekProgressListener = mySeekProgressListener;return musicPlay;}private static MySeekProgressListener mySeekProgressListener;public interface  MySeekProgressListener{void onMySeekProgressData(String totleTime, String currentTime, int finishStatus);}/*** 是否在进行播放* @return*/public boolean isPlayIng(){return player.mediaPlayer.isPlaying();}/*** 释放资源*/public void release(){player.mediaPlayer.release();}public void play() {new Thread(new Runnable() {@Overridepublic void run() {if (player.mediaPlayer.isPlaying() || getPlayStatus() == PlayStatus.PLAYING) {player.pause();setPlayStatus(PlayStatus.PAUSE);} else if(getPlayStatus() == PlayStatus.NOPLAY || getPlayStatus() == PlayStatus.FINISH){if(getPlayStatus() == PlayStatus.FINISH){player.mediaPlayer.reset();//重置MediaPlayer到初始化状态player.mediaPlayer.seekTo(0);//须将播放时间设置到0;这样才能在下次播放是重新开始,否则会继续上次播放}player.playUrl(URLMUSIC);setPlayStatus(PlayStatus.PLAYING);}else if(getPlayStatus() == PlayStatus.PAUSE){player.start();//继续播放setPlayStatus(PlayStatus.PLAYING);}}}).start();}/*** 开始播放*/public void startPlay() {new Thread(new Runnable() {@Overridepublic void run() {}}).start();}/*** 停止播放*/public void stopPlay() {}/*** 继续播放*/public void continuePlay() {}private static void initSetMediaPlaylistener(){/*player.mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {Long totleLong = new Long((long) player.mediaPlayer.getDuration());mySeekProgressListener.onMySeekProgressData(totleLong,0L,100);LogUtil.i(TAG, mp.getDuration()+"我已完成啦!!!!");}});*/player.mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {@Overridepublic void onBufferingUpdate(MediaPlayer mp, int percent) {Long totleLong = new Long((long) player.mediaPlayer.getDuration());Long currentLong = new Long((long) player.mediaPlayer.getCurrentPosition());String totleTime = formatter.format(mp.getDuration());String currentTime = formatter.format((mp.getCurrentPosition()));LogUtil.e(TAG,"totle:  " +totleTime+"当前:  " + currentTime);if(mp.isPlaying()){//减少误差,避免得到getDuration()的时间出问题---->在这里花费了好多的时间mySeekProgressListener.onMySeekProgressData(totleTime,currentTime,0);if(totleTime.equals(currentTime)){//用这样的方式判断完成,减少时间的误差LogUtil.e(TAG,"我进来啦!!!");setPlayStatus(PlayStatus.FINISH);player.mediaPlayer.pause();// player.mediaPlayer.release();}}}});}public class SeekBarChangeEvent implements SeekBar.OnSeekBarChangeListener {int progress;@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {LogUtil.e(TAG,"totle:  " +player.mediaPlayer.getDuration());this.progress  = progress * player.mediaPlayer.getDuration() / seekBar.getMax();}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {player.mediaPlayer.seekTo(progress);if(getPlayStatus() == PlayStatus.FINISH) {play();}}}/*** 销毁时*/public void onDestroy() {if (player != null && player.mediaPlayer.isPlaying()) {player.stop();
//            player.mediaPlayer.pause();player = null;}setPlayStatus(PlayStatus.NOPLAY);}public void palyByMobileSevice(){Intent intent = new Intent();Uri uri = Uri.parse(URLMUSIC);intent.setDataAndType(uri, "audio/mp3");//  intent.setDataAndType(uri, "audio/*");这里可以改成audio/mp3intent.setAction(Intent.ACTION_VIEW);context.startActivity(intent);}
}
public class Player implements OnBufferingUpdateListener, OnCompletionListener,OnPreparedListener{public MediaPlayer mediaPlayer;private SeekBar seekBar;private Timer mTimer = new Timer();public Player(SeekBar seekBar) {super();this.seekBar = seekBar;try {mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setOnBufferingUpdateListener(this);mediaPlayer.setOnPreparedListener(this);} catch (Exception e) {e.printStackTrace();}mTimer.schedule(timerTask, 0, 1000);}TimerTask timerTask = new TimerTask() {@Overridepublic void run() {if (mediaPlayer == null)return;if (mediaPlayer.isPlaying() && seekBar.isPressed() == false) {handler.sendEmptyMessage(0);}}};Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {int position = mediaPlayer.getCurrentPosition();int duration = mediaPlayer.getDuration();if (duration >= 0) {long pos = seekBar.getMax() * position / duration;seekBar.setProgress((int) pos);}};};public void play() {mediaPlayer.start();}/*** * @param url*/public void playUrl(String url) {try {mediaPlayer.reset();mediaPlayer.setDataSource(url);mediaPlayer.prepare();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);// 通过异步的方式装载媒体资源/*mediaPlayer.prepareAsync();mediaPlayer.setOnPreparedListener(new OnPreparedListener() {@Overridepublic void onPrepared(MediaPlayer mp) {// 装载完毕回调mediaPlayer.start();}});*/} catch (IllegalArgumentException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalStateException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}public void pause() {mediaPlayer.pause();}public void start() {mediaPlayer.start();}public void stop() {if (mediaPlayer != null) {mediaPlayer.stop();mediaPlayer.release();mediaPlayer = null;}}@Overridepublic void onPrepared(MediaPlayer mp) {mp.start();Log.e("mediaPlayer", "onPrepared");}@Overridepublic void onCompletion(MediaPlayer mp) {Log.e("mediaPlayer", "onCompletion");}@Overridepublic void onBufferingUpdate(MediaPlayer mp, int percent) {seekBar.setSecondaryProgress(percent);int currentProgress = seekBar.getMax()* mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration();Log.e(currentProgress + "% play", percent + " buffer");}}
但是到了最后竟然忘记写权限了:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>否则就会播放不出来。报一些其他类型的错误。
好了,最后贴上项目地址:http://download.csdn.net/detail/androidstarjack/9690396
另外你觉得此篇文章对您有所帮助 请关注终端研发部,QQ交流群 :232203809
 
 

















