本文出自:http://blog.csdn.net/dt235201314/article/details/51341104
代码上传到github,欢迎start:https://github.com/JinBoy23520/TingTingMusic
一丶MediaPlayer
参考博文加强:扣丁学堂——MediaPlay(音乐播放)
二丶演示
三丶创建MusicService服务
这里贴出了后面涉及到的部分代码
/** * 实现功能: * 1、点击列表上的某首歌播放 * 2、点击播放按钮,从暂停转为播放状态 * 3、点击暂停按钮,从播放状态转为暂停状态 * 4、上一首 * 5、下一首 * 6、播放进度显示 * 7、播放模式 */ public class MusicPlayService extends Service implements MediaPlayer.OnCompletionListener,MediaPlayer.OnErrorListener{ private MediaPlayer mediaPlayer; private ArrayList基类BaseActivity(实现Demo中所有服务的绑定和解绑)mp3Infos; private int currentPosition;//列表当前位置 private MusicUpdateListener musicUpdateListener;//设置属性 private boolean isPause = false; //顺序播放、单曲循环、随机播放 public static final int ORDER_PLAY = 1; public static final int RANDOM_PLAY = 2; public static final int SINGLE_PLAY = 3; public int play_mode = ORDER_PLAY; //用于设置或者获得播放模式 public int getPlay_mode() { return play_mode; } public void setPlay_mode(int play_mode) { this.play_mode = play_mode; } //在fragment或者activity中轻松获得状态 public boolean isPause(){ return isPause; } //开启线程池 private ExecutorService es = Executors.newSingleThreadExecutor(); Runnable updateStatusRunnable = new Runnable() { @Override public void run() { while (true){ if(musicUpdateListener!=null){ musicUpdateListener.onPublish(getCurrentProgress()); } } } }; public MusicPlayService() { } Random random = new Random(); //用于监听当前歌曲播放完后,下一首该如何播放 @Override public void onCompletion(MediaPlayer mediaPlayer) { switch (play_mode){ case ORDER_PLAY: next(); break; case RANDOM_PLAY: play(random.nextInt(mp3Infos.size())); break; case SINGLE_PLAY: play(currentPosition); break; default: break; } } @Override public boolean onError(MediaPlayer mediaPlayer, int i, int i1) { mediaPlayer.reset(); return false; } class PlayBinder extends Binder{ public MusicPlayService getMusicPlayService(){ return MusicPlayService.this; } } @Override public void onCreate() { super.onCreate(); mediaPlayer = new MediaPlayer(); mp3Infos = MediaUtils.getMp3Infos(this); mediaPlayer.setOnCompletionListener(this); mediaPlayer.setOnErrorListener(this); //在进入每一个绑定service时,就监听进度改变事件,而状态改变监听则是在启动播放的时候 es.execute(updateStatusRunnable); } //启动线程就得销毁 @Override public void onDestroy() { super.onDestroy(); if(es!=null && es.isTerminated()){ es.shutdown(); es = null; } } @Nullable @Override public IBinder onBind(Intent intent) { return new PlayBinder(); } //点击列表上的某首歌播放 public void play(int position){ if(position>=0 && position<mp3Infos.size()){ Mp3Info mp3Info = mp3Infos.get(position); try { mediaPlayer.reset(); mediaPlayer.setDataSource(this, Uri.parse(mp3Info.getUrl())); mediaPlayer.prepare(); mediaPlayer.start(); currentPosition = position; }catch (IOException e){ e.printStackTrace(); } if(musicUpdateListener!=null){ musicUpdateListener.onChange(currentPosition); } } } //点击播放按钮,从暂停转为播放状态 public void start(){ if(mediaPlayer!=null && !mediaPlayer.isPlaying()){ mediaPlayer.start(); } } //点击暂停按钮,从播放状态转为暂停状态 public void pause(){ if(mediaPlayer.isPlaying()){ mediaPlayer.pause(); isPause = true; } } //下一首 public void next(){ if(currentPosition >= mp3Infos.size()-1){ currentPosition = 0; }else{ currentPosition++; } play(currentPosition); } //上一首 public void previous(){ if(currentPosition<=0){ currentPosition = mp3Infos.size()-1; }else{ currentPosition--; } play(currentPosition); } //更新状态的接口 public interface MusicUpdateListener{ public void onPublish(int progress); public void onChange(int position); } public void setMusicUpdateListener(MusicUpdateListener musicUpdateListener) { this.musicUpdateListener = musicUpdateListener; } //在音乐播放中,获得播放的位置信息 public int getDuration(){ return mediaPlayer.getDuration(); } //到目前为止,我都不知道这是干什么用的 public void seekTo(int msec){ mediaPlayer.seekTo(msec); } //返回当前的位置 public int getCurrentPosition(){ return currentPosition; } //获得当前位置 public int getCurrentProgress(){ if(mediaPlayer!=null && mediaPlayer.isPlaying()){ return mediaPlayer.getCurrentPosition(); } return 0; } //反馈状态 public boolean isPlaying(){ if(mediaPlayer!=null&&mediaPlayer.isPlaying()){ return mediaPlayer.isPlaying(); } return false; } }
/** * 自定义基础activity,用来让其他activity继承,作为工具activity,用于绑定服务 */ public abstract class BaseActivity extends FragmentActivity { protected MusicPlayService musicPlayService; private boolean isBound = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { MusicPlayService.PlayBinder playBinder = (MusicPlayService.PlayBinder)iBinder; musicPlayService = playBinder.getMusicPlayService(); musicPlayService.setMusicUpdateListener(musicUpdateListener); //绑定成功后调用监听onChange方法 musicUpdateListener.onChange(musicPlayService.getCurrentPosition()); } @Override public void onServiceDisconnected(ComponentName componentName) { musicPlayService = null; isBound = false; } }; private MusicPlayService.MusicUpdateListener musicUpdateListener = new MusicPlayService.MusicUpdateListener(){ @Override public void onPublish(int progress) { publish(progress); } @Override public void onChange(int position) { change(position); } }; public abstract void publish(int progress); public abstract void change(int position); //绑定服务 public void bindMusicPlayService(){ if(!isBound){ Intent intent = new Intent(this,MusicPlayService.class); bindService(intent,conn,BIND_AUTO_CREATE); isBound = true; } } //解除绑定服务 public void unbindMusicPlayService(){ if(isBound){ unbindService(conn); isBound = false; } } }欢迎页面中启动服务(启动页面出代码已贴出)
LocalSongsActivity实现监听,点击不同音乐播放不同歌曲
public class LocalSongsActivity extends BaseActivity implements View.OnClickListener,AdapterView.OnItemClickListener{ private ListView lv_local_songs_list; private ArrayList到这里,LocalSongsActivity此处的音乐就能播放了,切实现上一曲,下一曲,暂停等功能mp3Infos; private LocalSongsListAdapter localSongsListAdapter; private ImageView iv_backtrack,iv_album,iv_previous,iv_play,iv_next; private TextView tv_song_name1,tv_song_artist1; private RelativeLayout rl_music_play_control; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_local_songs); lv_local_songs_list = (ListView)findViewById(R.id.lv_local_songs_list); iv_backtrack = (ImageView)findViewById(R.id.iv_backtrack); iv_album = (ImageView) findViewById(R.id.iv_album); iv_play = (ImageView)findViewById(R.id.iv_play); iv_next = (ImageView)findViewById(R.id.iv_next); iv_previous = (ImageView)findViewById(R.id.iv_previous); tv_song_name1 = (TextView)findViewById(R.id.tv_song_name1); tv_song_artist1 = (TextView)findViewById(R.id.tv_song_artist1); rl_music_play_control = (RelativeLayout)findViewById(R.id.rl_music_play_control); rl_music_play_control.setOnClickListener(this); iv_play.setOnClickListener(this); iv_backtrack.setOnClickListener(this); iv_next.setOnClickListener(this); iv_previous.setOnClickListener(this); lv_local_songs_list.setOnItemClickListener(this); initDate(); } @Override protected void onDestroy() { super.onDestroy(); } @Override protected void onResume() { super.onResume(); //绑定播放服务 bindMusicPlayService(); } @Override protected void onPause() { super.onPause(); unbindMusicPlayService(); } /** * 初始化本地音乐列表 */ private void initDate() { mp3Infos = MediaUtils.getMp3Infos(this); System.out.println(mp3Infos.size()); localSongsListAdapter = new LocalSongsListAdapter(this,mp3Infos); localSongsListAdapter.notifyDataSetChanged(); lv_local_songs_list.setAdapter(localSongsListAdapter); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.iv_backtrack: finish(); break; case R.id.iv_play: if(this.musicPlayService.isPlaying()){ this.musicPlayService.pause(); iv_play.setImageResource(R.drawable.play); }else{ if(this.musicPlayService.isPause()){ this.musicPlayService.start(); iv_play.setImageResource(R.drawable.pause); }else { this.musicPlayService.play(0); iv_play.setImageResource(R.drawable.pause); } } break; case R.id.iv_next: this.musicPlayService.next(); iv_play.setImageResource(R.drawable.pause); break; case R.id.iv_previous: this.musicPlayService.previous(); iv_play.setImageResource(R.drawable.pause); break; case R.id.rl_music_play_control: Intent intent = new Intent(this,PlayUIActivity.class); startActivity(intent); overridePendingTransition(R.anim.abc_fade_in, R.anim.abc_fade_out); break; } } @Override public void onItemClick(AdapterView> adapterView, View view, int position, long id) { musicPlayService.play(position); iv_play.setImageResource(R.drawable.pause); } @Override public void publish(int progress) { } @Override public void change(int position) { //切换状态播放位置 changeUIStatus(position); } //回调播放状态下的UI设置 public void changeUIStatus(int position){ if(position>=0 && position<mp3Infos.size()){ Mp3Info mp3Info = mp3Infos.get(position); tv_song_name1.setText(mp3Info.getTitle()); tv_song_artist1.setText(mp3Info.getArtist()); if(musicPlayService.isPlaying()){ iv_play.setImageResource(R.drawable.pause); }else { iv_play.setImageResource(R.drawable.play); } //Bitmap albumBitmap = MediaUtils.getArtwork(this, mp3Info.getTitle(),mp3Info.getId(), mp3Info.getAlbumId(),true); Bitmap albumBitmap = MediaUtils.getArtwork(this,mp3Info.getId(), mp3Info.getAlbumId(),true,false); if(albumBitmap==null){ iv_album.setImageResource(R.drawable.music_play); }else{ iv_album.setImageBitmap(albumBitmap); } } } }