音乐播放器-容易实现播放、暂停、随机播放、音乐进度条(第一版)

音乐播放器--简单实现播放、暂停、随机播放、音乐进度条(第一版)
界面如下:
音乐播放器-容易实现播放、暂停、随机播放、音乐进度条(第一版)      音乐播放器-容易实现播放、暂停、随机播放、音乐进度条(第一版)     音乐播放器-容易实现播放、暂停、随机播放、音乐进度条(第一版)    音乐播放器-容易实现播放、暂停、随机播放、音乐进度条(第一版)

说明一下实现这个音乐播放器的思路。
首先,打开应用后查找手机上所有的音乐,放在Application中。这样做避免以后查找播放音乐的时候使用静态变量(上个应用就是应为大量使用静态变量,内存消耗太大,Activity老是被回收,所以这次直接把要使用的数据放在Application,使用的时候再取出来)
获取手机上所有音乐(有个缺点,就是所有是声音的文件都查找出来了,这部分以后还要优化,优化成自定义扫描目录,获获取手机上歌曲。)
代码如下:
<pre name="code" class="java"> private List<Music> musiclist;
 @Override
 public void onCreate() {
  super.onCreate();
  searchMusicONPhone();
 }
 /**
  * 查找手机上所有歌曲
  */
 private void searchMusicONPhone(){
 
  Cursor cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
    null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
  musiclist = new ArrayList<Music>();
  if(cursor == null || cursor.getCount() <= 0){
   setMusiclist(musiclist);
  }else{
   while(cursor.moveToNext()){
    Music music = new Music();
    music.setId(cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Media._ID))); //歌曲ID
    music.setTitle(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE)));//歌曲的名称
    music.setAlbum(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM))); //歌曲的专辑名
    music.setArtists(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST))); //歌曲的歌手名
    music.setTimes(toTime(cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION))));//歌曲的总播放时长
    music.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));//歌曲文件的路径
    music.setSize(cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)));//歌曲文件的大小
    musiclist.add(music);
   }
   setMusiclist(musiclist);
  }
  if(cursor != null){
   cursor.close();
   cursor = null;
  }

 }

 public List<Music> getMusiclist() {
  return musiclist;
 }

 public void setMusiclist(List<Music> musiclist) {
  this.musiclist = musiclist;
 }



在Activity中获取歌曲代码如下: 
mApplication = (MyApplication)getApplication();
musiclist = mApplication.getMusiclist();



第二步:当点击播放音乐的时候,传递给Service音乐id,在后台打开音乐。代码如下:
1、在<manifest>中声明<service>    
 <service
            android:name="com.mini.service.MusicService">
            <intent-filter>
                <action android:name="com.app.media.music_service"/>
            </intent-filter>
   </service>


2、创建自己的Service
package com.mini.service;

import java.io.IOException;
import java.util.List;

import com.mini.MyApplication;
import com.mini.R;
import com.mini.activity.base.BaseActivity;
import com.mini.bean.Music;
import com.mini.constans.Constants;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.provider.MediaStore;

@SuppressLint("HandlerLeak")
public class MusicService extends Service implements MediaPlayer.OnCompletionListener {

 private MyApplication mApplication;
 private List<Music> mList;
 private MediaPlayer mPlayer;
 private int op;
 private Uri uri;
 private int id;
 private int position;
 private int currentTime;
 private Handler mHandler;
 private int duration;
 
 @Override
 public void onCreate() {
  super.onCreate();
  mApplication = (MyApplication)getApplication();
  mList = mApplication.getMusiclist();
  if(mPlayer != null){
   mPlayer.reset();
   mPlayer.release();
   mPlayer = null;
  }
  mPlayer = new MediaPlayer();
  mPlayer.setOnCompletionListener(this);
 }

 @SuppressWarnings("deprecation")
 @Override
 public void onStart(Intent intent, int startId) {
  super.onStart(intent, startId);
  position = intent.getIntExtra("idOption", -1);
  if(position == -1){
  }else{
   playMusic();
  }
 
  op = intent.getIntExtra("op", -1);
   switch (op) {
   case Constants.MUSIC_PLAY:
    playing();            
    break;
   case Constants.MUSIC_PAUSE:
    pause();
    break;
   case Constants.MUSIC_STOP:
    stop();        
    break;
   case Constants.PROGRESS_CHANGE:
    currentTime = intent.getExtras().getInt("progress");
    mPlayer.seekTo(currentTime);
    break;
   case -1:
    setUp();
    initBorderCastService();
    break;
   default:
    break;
   }
  }
 
 
 /**
  * 初始化歌曲信息、进度条
  */
 private void setUp(){
  final Intent intent = new Intent();
  intent.setAction(Constants.MUSIC_DURATION);
   try {
   
    if(!mPlayer.isPlaying()){
     mPlayer.prepare();
    }
    mPlayer.setOnPreparedListener(new OnPreparedListener() {
     @Override
     public void onPrepared(MediaPlayer mp) {
      mHandler.sendEmptyMessage(1);
     }
    });
   
   } catch (IllegalStateException e) {
    e.printStackTrace();
   } catch (IOException e) {
    e.printStackTrace();
   }
   duration = mPlayer.getDuration();
   intent.putExtra("duration", duration);
   sendBroadcast(intent);
 }
 
 /**
  * 初始化广播机制
  */
 private void initBorderCastService(){
  final Intent intent = new Intent();
  intent.setAction(Constants.MUSIC_CURRENT);
  if(mHandler == null){
   mHandler = new Handler(){
    public void handleMessage(Message msg){
     if(msg.what == 1){
      currentTime = mPlayer.getCurrentPosition();
      intent.putExtra("currentTime", currentTime);
      if(position == -1){
       intent.putExtra("position",intent.getIntExtra("position", -1));
      }else{
       intent.putExtra("position",position);
      }
     
      sendBroadcast(intent);
     }
     mHandler.sendEmptyMessageDelayed(1, 1000);
    }
   };
  }
 }
 

 /**
  * 播放歌曲
  */
 private void playing(){
  if(mPlayer != null){
   mPlayer.start();
  }
 }
 
 /**暂停*/
 private void pause() {
  if (mPlayer != null) {
   mPlayer.pause();
  }
 }
 
 /** 停止*/
 private void stop() {
  if (mPlayer != null) {
   mPlayer.stop();
   try {
    mPlayer.prepare();
    mPlayer.seekTo(0);
   } catch (IllegalStateException e) {
    e.printStackTrace();
   } catch (IOException e) {
    e.printStackTrace();
   }
   mHandler.removeMessages(1);

  }
 }
 @Override
 public IBinder onBind(Intent intent) {
  return null;
 }

 private static  int i;
 @Override
 public void onCompletion(MediaPlayer mp) {
  nextMusic();
 }

 private void nextMusic() {
  switch (BaseActivity.loop_method) {
  case Constants.LOOP_ONE:
   break;
  case Constants.LOOP_ALL:
   if (position == mList.size()-1) {
    position = 0;
   } else if (position < mList.size()-1) {
    position++;
   }
   break;
  case Constants.LOOP_NONE:
   position = BaseActivity.mRandomID();
   break;
  default:
   break;
  }
  playMusic();
  setUp();
  initBorderCastService();
  playing();
 }
 
 public void playMusic(){
  id = mList.get(position).getId();
  uri = Uri.withAppendedPath(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id + "");
  try {
   mPlayer.reset();
   mPlayer.setDataSource(this,uri);
   mPlayer.prepare();
   mPlayer.start();
  } catch (IllegalStateException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 
 }

}
3、播放事件
  /**
   * 随机播放音乐事件
   */
  radom_begin_music.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
    myPosition = mRandomID();
    Intent intent = new Intent();
    intent.setAction("com.app.media.music_service");
    intent.putExtra("idOption", myPosition);
    startService(intent);
    flag = Constants.MUSIC_PAUSE;
   }
  });


接下来是细节问题,比如进度条改变,暂停音乐,继续播放。。
1、进度条改变是通过Service不断发送广播,然后在Activity中接收广播
 
/**
  * 接收广播,更新歌曲的进度
  */
 protected BroadcastReceiver musicReceiver = new BroadcastReceiver(){
  @Override
  public void onReceive(Context context, Intent intent) {
   String actionString = intent.getAction();
   if(actionString.equals(Constants.MUSIC_CURRENT)){
    currentPosition = intent.getExtras().getInt("currentTime");
    position = intent.getExtras().getInt("position");
    music_durtion_sBar.setProgress(currentPosition);
    music_preform_time.setText(toTime(currentPosition));
    bottomUpdate();
   }else if(actionString.equals(Constants.MUSIC_DURATION)){
    duration = intent.getExtras().getInt("duration");
    music_durtion_sBar.setMax(duration);
   }
  }
 };

2、底部的暂停播放按钮事件
  /**
   * 底部播放暂停按钮
   */
  bottom_play_btn.setOnClickListener(new OnClickListener() {
   @Override
   public void onClick(View v) {
   
    switch (flag) {
    case Constants.MUSIC_PAUSE:
     pause();
     break;
    case Constants.MUSIC_PLAY:
     play();
     break;
    default:
     break;
    }
   }
  });

 /**
  * 播放音乐
  */
 public void play() {
  flag = Constants.MUSIC_PAUSE;
  bottom_play_btn.setBackgroundResource(R.drawable.bottom_play);
  Intent intent = new Intent();
  intent.setAction("com.app.media.music_service");
  intent.putExtra("op", Constants.MUSIC_PLAY);// 向服务传递数据
  startService(intent);
 }
 
 /**
  * 暂停
  */
 public void pause() {
  flag = Constants.MUSIC_PLAY;
  bottom_play_btn.setBackgroundResource(R.drawable.bottom_pause);
  Intent intent = new Intent();
  intent.setAction("com.app.media.music_service");
  intent.putExtra("op", Constants.MUSIC_PAUSE);
  startService(intent);
 }



3、下一首事件代码
 /**
  * 下一首
  */
 public  void nextOne() {
  stop();
  setup();
  playNext();
 }
 
 public void playNext() {
  flag = Constants.MUSIC_PAUSE;
  int music_id = position;
 
  switch (loop_method) {
  case Constants.LOOP_ONE:
   music_id = position;
   break;
  case Constants.LOOP_ALL:
   if (position == musiclist.size()-1) {
    position = 0;
    music_id = position;
   } else if (position < musiclist.size()-1) {
    position++;
    music_id = position;
   }
   break;
  case Constants.LOOP_NONE:
   music_id = mRandomID();
   break;
  default:
   break;
  }
  bottom_play_btn.setBackgroundResource(R.drawable.bottom_play);
  Intent intent = new Intent();
  intent.setAction("com.app.media.music_service");
  intent.putExtra("idOption", music_id);// 向服务传递数据
  startService(intent);
 }

 /**
  * 停止播放音乐
  */
 private void stop() {
  unregisterReceiver(musicReceiver);
  Intent intent = new Intent();
  intent.setAction("com.app.media.music_service");
  intent.putExtra("op", Constants.MUSIC_STOP);
  startService(intent);
 }
 
 /**
  * 初始化
  */
 private void setup() {
  init();
 }




这里可以下载源码:http://download.csdn.net/detail/yan943789510/8615689