Android自定义音乐播放器

来源:互联网 发布:linux search命令 编辑:程序博客网 时间:2024/04/30 09:40

因为项目需要,要做一个自定义的音乐播放器,要求简单但是稳定。代码已经调试好了,稳定性还不错吧~考虑到商业保密性就先不上图了,到时产品上市之后再补上。先描述一下功能:音乐播放时,总共有两个元素在动(音乐进度条,模拟现场乐团演奏的方式刷图),上一首、下一首、播完一首自动播下一首、循环播放、搜索相应目录下所有音乐文件、跑马灯效果显示音乐文字。

上代码:

MusicPlayerActivity.java

package com.ideal.swfplayer;/***************************************************************************************************** * 播放TF卡中的音频文件,主要角色是MediaPlayer,详细资料参考http://blog.csdn.net/runninglion/article/details/41909989* * ***************************************************************************************************/  import java.io.File;import java.util.ArrayList;import java.util.List;import android.media.MediaPlayer;import android.media.MediaPlayer.OnCompletionListener;import android.os.Bundle;   import android.os.Handler;import android.annotation.SuppressLint;import android.app.Activity;   import android.content.Intent;import android.view.KeyEvent;import android.widget.ImageView;import android.widget.SeekBar;import android.widget.TextView;  @SuppressLint("HandlerLeak") public class MusicPlayerActivity extends Activity {      private MediaPlayer mp;    private String path,mfilepath;    private SeekBar mseekbar;     private TextView musicname;    private int refress_pic_time=100;    private int refress_seekbar_time=500;    private ImageView mmusic_pic,mplay ;     private int pic_number=0;    private String[] ext={".mp3", ".wav",".MP3",".WAV"};//定义我们要查找的文件格式      private List<String> list;     private int currIndex=0;    private boolean flash_state=false;    private int [] pic={R.drawable.music_pic1,R.drawable.music_pic2,R.drawable.music_pic3,R.drawable.music_pic4,R.drawable.music_pic5,                R.drawable.music_pic6,R.drawable.music_pic7,R.drawable.music_pic8,R.drawable.music_pic9,R.drawable.music_pic10};    @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_music);         //初始化UI界面        InitUI();        //初始化配置        InitConfig();        //加载视频        LoadVoice();    }        //更新seekbar进度条    Handler handler = new Handler();      Runnable updateThread = new Runnable(){       public void run() {      //获得歌曲的长度并设置成播放进度条的最大值     mseekbar.setMax(mp.getDuration());         //获得歌曲现在播放位置并设置成播放进度条的值       mseekbar.setProgress(mp.getCurrentPosition());           //每次延迟refress_seekbar_time毫秒再启动线程           handler.postDelayed(updateThread, refress_seekbar_time);       }      };          //刷新图片,实现flash效果    Handler pic_handler = new Handler();      Runnable pic_updateThread = new Runnable(){       public void run() {      //循环播放十张图片     if(pic_number>=10)     pic_number=0;          mmusic_pic.setImageResource(pic[pic_number]);          pic_number++;      //每次延迟refress_seekbar_time毫秒再启动线程        pic_handler.postDelayed(pic_updateThread, refress_pic_time);       }      };          //初始化UI界面    private void InitUI() {mmusic_pic = (ImageView)this.findViewById(R.id.music_pic);mplay = (ImageView)this.findViewById(R.id.music_play);musicname = (TextView)this.findViewById(R.id.music_name);mseekbar = (SeekBar)this.findViewById(R.id.music_seekbar);}    //初始化配置private void InitConfig() {mp=new MediaPlayer();list = new ArrayList<String>();//获得前一个界面传来的文件路径Intent mIntent = getIntent();    path = mIntent.getStringExtra("music_path");    //获得前一个界面传来的音乐搜索目录    mfilepath = mIntent.getStringExtra("file_path");    File file =new File(mfilepath);    //查找该目录下所有的音乐文件    search(file,ext);}//加载音频private void LoadVoice() {musicname.setText(GetPathName(path));try{         mp.setDataSource(path);//加载音频,进入Initialized状态。        mp.prepare();        mp.start();       //为MediaPlayer的播放完成讲件绑定市件监听器        mp.setOnCompletionListener(new OnCompletionListener() {                       @Override            public void onCompletion(MediaPlayer mp) {            next();                }           });        //加载刷新seekbar进度条        handler.post(updateThread);         //十张图刷新        pic_handler.postDelayed(pic_updateThread, refress_pic_time);        flash_state=true;        }catch (Exception e) {e.printStackTrace();}}    // 搜索音乐文件 ,将音乐路径存到list中    private void search(File file, String[] ext) {          if (file != null) {             if (file.isDirectory()) {                  File[] listFile = file.listFiles();                  if (listFile != null) {                      for (int i = 0; i < listFile.length; i++) {                          search(listFile[i], ext);                      }                  }              } else {                  String filename = file.getAbsolutePath();                  for (int i = 0; i < ext.length; i++) {                      if (filename.endsWith(ext[i])) {                          list.add(filename);                        break;                      }                  }              }          }       }     //从音乐路径中提取出音乐名字    private String GetPathName(String mpath){    String[] strarray=mpath.split("/"); return strarray[strarray.length-1];     }        //上一首      private void previous() {          if((currIndex-1)>=0){              currIndex--;             if (list.size() > 0 && currIndex < list.size()) {             musicname.setText(GetPathName(list.get(currIndex)));            path = list.get(currIndex);            //该句的作用是消除上一次pm的资源,让mp回到ide状态,可了解它的生命周期            mp.reset();            try{            //必须先执行setDataSource之后才能执行prepare        mp.setDataSource(path);//加载音频,进入Initialized状态。        mp.prepare();//进入prepared状态。        mp.start();         //监听播放完成        mp.setOnCompletionListener(new OnCompletionListener() {                       @Override            public void onCompletion(MediaPlayer mp) {            //播放完成之后自动跳到下一首            next();                }           });        //加载音乐进度条与刷图        if(!flash_state){        handler.post(updateThread);         pic_handler.postDelayed(pic_updateThread, refress_pic_time);        }            }catch (Exception e) {e.printStackTrace();}                           }else{                              }        }else{          currIndex=list.size()-1;             if (list.size() > 0 && currIndex < list.size()) {             musicname.setText(GetPathName(list.get(currIndex)));            path = list.get(currIndex);            mp.reset();            try{         mp.setDataSource(path);        //加载音频,进入Initialized状态。        mp.prepare();//进入prepared状态。         mp.start();        mp.setOnCompletionListener(new OnCompletionListener() {                       @Override            public void onCompletion(MediaPlayer mp) {            next();                }           });        if(!flash_state){        handler.post(updateThread);         pic_handler.postDelayed(pic_updateThread, refress_pic_time);        }            }catch (Exception e) {e.printStackTrace();}                            }else{                              }           }      }        //下一自首      private void next() {          if(currIndex+1<list.size()){              currIndex++;            if (list.size() > 0 && currIndex < list.size()) {                 musicname.setText(GetPathName(list.get(currIndex)));            path = list.get(currIndex);            mp.reset();            try{         mp.setDataSource(path);        //加载音频,进入Initialized状态。        mp.prepare();//进入prepared状态。        mp.start();      //为MediaPlayer的播放完成讲件绑定市件监听器        mp.setOnCompletionListener(new OnCompletionListener() {                       @Override            public void onCompletion(MediaPlayer mp) {            next();                }           });        if(!flash_state){        handler.post(updateThread);         pic_handler.postDelayed(pic_updateThread, refress_pic_time);        }                    }catch (Exception e) {e.printStackTrace();}                            }else{                               }         }else{          currIndex=0;             if (list.size() > 0 && currIndex < list.size()) {             musicname.setText(GetPathName(list.get(currIndex)));            path = list.get(currIndex);            mp.reset();            try{         mp.setDataSource(path);        //加载音频,进入Initialized状态。        mp.prepare();//进入prepared状态。        mp.start();         mp.setOnCompletionListener(new OnCompletionListener() {                       @Override            public void onCompletion(MediaPlayer mp) {            next();                }           });        if(!flash_state){        handler.post(updateThread);         pic_handler.postDelayed(pic_updateThread, refress_pic_time);        }            }catch (Exception e) {e.printStackTrace();}                          }else{                              }           }      }       //检测监听事件public boolean onKeyDown(int keyCode, KeyEvent event) {//下一首if (keyCode == KeyEvent.KEYCODE_R) {            next();        //上一首} else if (keyCode == KeyEvent.KEYCODE_L) {previous();    //暂停或开始} else if (keyCode == KeyEvent.KEYCODE_S) {if(!mp.isPlaying()){mp.start();handler.post(updateThread); pic_handler.postDelayed(pic_updateThread, refress_pic_time); flash_state=true;mplay.setImageResource(R.drawable.music_stop);//设置暂停标记}else{mp.pause();handler.removeCallbacks(updateThread);pic_handler.removeCallbacks(pic_updateThread);flash_state=false;mplay.setImageResource(R.drawable.music_play);//设置暂停标记}//退出} else if (keyCode == KeyEvent.KEYCODE_B) {//这两句很重要,如果不加这两句而直接退出会出现异常,原因是该线程还未终止pic_handler.removeCallbacks(pic_updateThread);handler.removeCallbacks(updateThread);if (mp != null) {// 如果为空,我们调用释放资源的方法时就会出现空指针异常。  mp.release();// 释放音频资源,一定要释放,不然会造成推出之后还播放音乐以及内存异常溢出 mp = null;       }MusicPlayerActivity.this.finish();} return super.onKeyDown(keyCode, event);}}  

虽然没有很核心的算法,但是读者可以参考下具体实现的一些细节处理。比如说怎么处理MediaPlayer的生命周期,关掉应用之前必须释放音乐资源,释放音乐之前必须要先杀死相关进程,否则会退出异常。读者如有疑问可以提出,在线回答~

0 0