初识安卓之自定义音乐播放器

public class MainrActivity extends Activity {
    private MediaPlayer mediaPlayer;
    private ImageButton ppIB;
    private SeekBar audioSB;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        ppIB=(ImageButton) findViewById(R.id.ppIB);
        audioSB = (SeekBar) findViewById(R.id.audioSB);
    }
    
 //退出程序时,停止播放
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer=null;
    }
 
 
    public void onClick(View view) throws Exception{
        //如果根本没有播放器对象,则需要现得到一个播放器,否则一切操作都是空指针
        if(mediaPlayer==null){
        String url = "/mnt/sdcard/ttpod/song/Poker Face-Lady GaGa.mp3"; // your URL here
        //创建媒体播放器
        mediaPlayer = new MediaPlayer();
        //设置音频流的类型
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        //设置音频源
        mediaPlayer.setDataSource(url);
        
        //普通缓冲加载,缺点:没缓冲完时,下面的代码都不能执行
        //mediaPlayer.prepare(); // might take long! (for buffering, etc)
        
        //异步缓冲:如果播放的是网络资源,可能缓冲时间会很长,这是最好用异步缓冲,它
        //在新线程中加载数据,加载是不影响下面代码的继续执行      
        mediaPlayer.prepareAsync(); 
        
        //弹出一个进度条形的圆形缓冲对话框
        showDialog();
        
        //添加缓冲完毕监听器,把缓冲完后要做的事写在里面,不要影响其他代码
        mediaPlayer.setOnPreparedListener(prelistener);
        
        //以下两行注释掉的代码写到缓存完毕监听器对象的方法中取
/*        mediaPlayer.start();
        //另写一个函数来控制进度条的自动行走
        handleSeekbar();*/
        
        //设置当播放器完成播放后的事件监听        
        mediaPlayer.setOnCompletionListener(comlistener);
        }
        //如果非空(已经有了播放器对象了,不会空指针)而且是正在播放,点击按钮,就可以把播放器停止下来
        else if(mediaPlayer.isPlaying()){
            mediaPlayer.pause();
        }
        //如果非空且已经暂停了,点击按钮就可以开始播放
        else {
            mediaPlayer.start();
        }
        //控制按钮的图形:判断当前是否在播放,是设置为播放按钮,不是设置为停止按钮
        ppIB.setImageResource(mediaPlayer.isPlaying()?android.R.drawable.ic_media_pause:android.R.drawable.ic_media_play);
    }
    private void handleSeekbar() {
 
 
        // TODO Auto-generated method stub
        //设置进度条的相对最大值为播放器所播放的音乐的持续时间
        audioSB.setMax(mediaPlayer.getDuration());
        //开启新线程设置进度条每一秒的位置
        new Thread(){
            @Override
            public void run() {
                //开启循环,不停的设置进度条的即时位置
                while(mediaPlayer!=null){
                    //只有播放器正在播放,而且它的进度条没有被拖动时,才能设置进度条的动作
                    if(mediaPlayer.isPlaying()&&!audioSB.isPressed())
                        audioSB.setProgress(mediaPlayer.getCurrentPosition());
                    try {
                        //一秒钟动一下
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
 
            }
        }.start();
        //为了能拖动进度条来播放,对进度条进行拖动事件的监听
        audioSB.setOnSeekBarChangeListener(listener);
    }
    //利用内部类完成创建播放器播放完成事件监听对象
    private OnCompletionListener comlistener=new OnCompletionListener(){
        //当播完一首歌后,停止播放器,释放对象资源,等待回收,进度条回到开始,按钮变为开始按钮
        @Override
        public void onCompletion(MediaPlayer mp) {
            
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer=null;
            audioSB.setProgress(0);
            ppIB.setImageResource(android.R.drawable.ic_media_play);
        }
        
    };
    //利用内部类完成创建进度条改变监听器对象。
private OnSeekBarChangeListener listener=new OnSeekBarChangeListener() {
    @Override
    //当不再拖动进度条时监听
    public void onStopTrackingTouch(SeekBar seekBar) {
        //当播放器对象已经存在(避免了还没播放就拖动时播放器对象的空指针异常)拖到哪里,就从哪里开始播
        if(mediaPlayer!=null)
        mediaPlayer.seekTo(audioSB.getProgress());
    }
    @Override
    //当点住进度条的时候监听
    public void onStartTrackingTouch(SeekBar seekBar) {
        
    }
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
            boolean fromUser) {
        
    }
};
OnPreparedListener prelistener=new OnPreparedListener(){
    @Override
    public void onPrepared(MediaPlayer mp) {
        //缓冲完了取消提示对话框
        dialog.dismiss();
        mediaPlayer.start();
        //另写一个函数来控制进度条的自动行走
        handleSeekbar();
        //缓冲完了就可以点击播放,改变按钮形状了,如果这里不写这一句,外面点播放,在缓冲时,还没有播放器对象,所以按钮图标也不会改变
        ppIB.setImageResource(mediaPlayer.isPlaying()?android.R.drawable.ic_media_pause:android.R.drawable.ic_media_play);
    }    
   };
private ProgressDialog dialog;
   //弹出一个进度条型对话框
   public void showDialog(){
       dialog = new ProgressDialog(this);
       //样式为圆形
       dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
       //显示几行信息
       dialog.setMessage("正在缓冲请稍后...");
       //此对话框不可以被取消,挡住后面的界面
       dialog.setCancelable(false);
       dialog.show();
   }
}
原文地址:https://www.cnblogs.com/94007boy/p/2797477.html