在做App的时候,为了使App更加的吸引人,我们通常会加入一些多媒体功能,这也是Android中非常重要的功能之一,在刚学Android的时候,自己尝试着模仿QQ音乐做了一款音视频播放器,虽然做的不怎么样,但是大体的功能都实现了。在之后,我也不断的完善,有了一些自己的见解(源码地址都在文章末)

        首先是Android中的音频播放功能,在这里我主要涉及到的是MediaPlayer类,这个类中的方法不全讲,涉及到细节的我知道的也不是很多,主要还是要看源代码。在此我只来讲述它的使用。

         播放音频文件,首先要找到它的位置,然后生成MediaPlayer的新对象,调用相应的方法,加载相应位置的文件,进行播放。

        文件的位置主要包括三个来源:1用户在文件中自带的Resource资源2SD卡或其它路径下的文件3网络上的文件

1播放Resource资源下的音频文件: 

if(this.player == null){          //   this.player = new MediaPlayer();       this.player = MediaPlayer.create(context, R.raw.a1);         //    this.player.prepare()   ;            }     //监听器判断是否结束     this.player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {// TODO Auto-generated method stub     stop();}});     this.player.start();   }

如果res文件夹下没有raw文件,直接新建一个raw文件,然后放入音频视频即可。

2播放SD卡或其他路径下的文件:

       MediaPlayer   mediaplayer = new MediaPlayer();     //生成一个MediaPlayer的对象       mediaplayer.setDataSource("/sdcard/Wiz Khalifa-See you again.mp3");   //装载音频文件的位置       mediaplayer.prepare();                                                                                                         //准备       mediaplayer.start();                                                                                                            //开始播放

setDataSource函数的参数为你播放文件的位置,必须在start之前prepare,简单的四句代码,即可播放音乐

3播放网络上的文件:

Uri uri = Uri.parse("http://192.168.0.135:8080/jsonweb/WebRoot/musics/starj.mp3"); //     Uri uri = Uri.parse("http://192.168.0.135:8080/raw1/starj.mp3");  media = MediaPlayer.create(startmusic.this, uri);  media.setOnPreparedListener(new OnPreparedListener(){ @Overridepublic void onPrepared(MediaPlayer mp) {// TODO Auto-generated method stubmedia.start();}   });

我们是否感觉非常的简单,确实几句代码就搞定了,但是在实现了这个播放的效果后,我们会感觉功能很单一,怎样去暂停音乐后播放,怎样快进,快退音乐,怎样去通过进度条控制,为何关闭了当前的Activity,音乐还在播放。或者其他的一些功能,接下来我就以播放SD卡路径下的音乐作为例子来实现这些功能。(还会延伸一些知识点)

MediaPlayer常用的方法(如下图,看不懂可上网查阅)

Android多媒体功能的实现上(音频,视频,相机,录音)_第1张图片

功能1 :实现音乐的暂停播放和停止播放(需用到prepare ,start,pause,stop,reset函数,以按钮的形式实现)

//播放音乐    public  void bofang() throws IllegalStateException, IOException {     if( mediaplayer == null){                      mediaplayer = new MediaPlayer();     //生成一个MediaPlayer的对象           mediaplayer.setDataSource("/sdcard/Wiz Khalifa-See you again.mp3");   //装载音频文件的位置                                                                                                          }     if(flag == 0 || flag == 2)        mediaplayer.prepare();               //准备       mediaplayer.start();                                                                                                                //开始播放    }       //暂停音乐      public   void   zanting(){        if(mediaplayer != null && mediaplayer.isPlaying()){                           mediaplayer.pause();               flag =1;        }          }      //停止音乐      public  void   tingzhi(){        if(mediaplayer != null && mediaplayer.isPlaying()){          mediaplayer.stop();          mediaplayer.reset();   //使mediapalyer处于空闲状态
          mediaplayer.release();  //切记停止音乐后,一定要把它释放掉          mediaplayer = null;    //使mediaplayer为空          flag =2;        }      }

以上三个函数可以实现播放当前暂停处的音乐,暂停哪里就播放哪里,停止播放为从头开始播放。使用了MediaPlayer提供的方法。此代码中最重要的一点是mediaplayer这个对象,也就是你new的这个对象,如果你只播放一首歌,那么就new 一次,如果你要播放很多歌那就new 很多次。也就是说new出的这个对象,代表着相对应你选择的歌曲的生命周期,所有的功能都在这个对象上完成。如果有很多歌,就多new几个。

功能 2 :使用进度条来控制音乐的快进快退,播放选到的位置,同步播放文件
此功能需要用到seekbar控件的功能,需要了解seekbar控件的方法

xml文件seekbar属性

  

以上xml文件显示的就是一个普通的进度条控件,现在需要对它进行操作,分为4个功能:

1 为进度条设置播放音频的时间长度,也就是说一个进度条代表一首歌的长度

seekbar.setMax(mediaplayer.getDuration());   //给seekbar添加具体的时间

这句代码使用了setMax方法和getDuration方法,获得当前mediaplayer对象的一首歌的长度然后赋值给进度条

2 使进度条能够与音频文件实现同步,音频文件播放到哪,进度条就在哪

 public class seekbartongbu implements Runnable{ @Overridepublic void run() {// TODO Auto-generated method stubwhile(true){try {Thread.sleep(1000);seekbar.setProgress(mediaplayer.getCurrentPosition()); //获得当前播放的进度值} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

这里同步的话,必须使用线程,主线程用来播放音乐,子线程用来同步音乐,用到了setProgress方法和getCurrentPosition方法,获得当前音乐文件的播放位置,然后赋值给seekbar.

3 显示当前音乐的播放时间和音乐的总时间

 

 用两个Textview控件来显示时间,并且把它们俩放到seekbar的两端                      longshijian = mediaplayer.getDuration();                      longshijian1 = new haomiaotoshijian().formattime(longshijian);                      zongshijian.setText(longshijian1);

获取当前mediaplayer对象的长度,因为getDuration方法得到的是音乐文件的总时长也就是毫秒数,所有需要把它转换为正常的时间显示:

public class haomiaotoshijian {    public haomiaotoshijian(){  } //把毫秒数变成时间格式 如 01:00 public  String  formattime(long time){   time = time/ 1000;       String strHour = "" + (time/3600);       String strMinute = "" + time%3600/60;       String strSecond = "" + time%3600%60;       strHour = strHour.length() < 2? "0" + strHour: strHour;       strMinute = strMinute.length() < 2? "0" + strMinute: strMinute;       strSecond = strSecond.length() < 2? "0" + strSecond: strSecond;       String strRsult = "";               if (!strHour.equals("00"))       {           strRsult += strHour + ":";       }               if (!strMinute.equals("00"))       {           strRsult += strMinute + ":";       }               strRsult += strSecond;               return strRsult; }

转化好后赋给TextView控件即可

4 实现拉动进度条,播放相对应的位置

实现OnSeekBarChangeListener接口,重写三个方法OnProgressChanged,OnStartTrackingTouch,OnStopTrackingTouch这三个方法

@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {// TODO Auto-generated method stubString nowtime = new haomiaotoshijian().formattime(progress);//Log.i(TAG, progress+"");new chuandishuju().setCurrentprogress(progress); if(nowtime.contains(":")){ bofangshijian.setText(nowtime); } elsebofangshijian.setText("00:"+nowtime); } @Overridepublic void onStartTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stub} @Overridepublic void onStopTrackingTouch(SeekBar seekBar) {// TODO Auto-generated method stubif(bofangmusic.player != null) bofangmusic.player.seekTo(seekbar.getProgress());else{xiayishoumusic.player.seekTo(seekbar.getProgress());}}

onProgressChanged方法:当进度条改变时,触发的操作

onStartTrackingTouch方法 :进度条刚开始拉动,触发的操作

onStopTrackingTouch 方法 :进度条停止拖动发生的操作

这四个功能实现后,就完成了一个简单的对音频文件的操作了,简单的功能就这样完成了,如果你想添加更多的复杂的功能,只需要在这个基础上自己改动即可,有什么不对的地方,还请大家指出,源代码中的音频的播放地址根据自己所放文件的地址填写。

源代码地址:http://download.csdn.net/detail/danielntz/9565737

在完成了以上的功能后,当我们关闭此程序后,发现音乐还在响,这是因为Mediaplayer本身是一个后台服务的类,它与程序也就是Activity是分开的,较好一点的理解就是程序是一个进程,Mediaplayer是一个进程,关闭程序只是把程序的进程关闭了,Mediaplayer的进程还在执行,所以音乐还在响。(我在魅族和中兴两部手机上做了测试,因为魅族系统是对Android系统的改进,所以有些情况不会发生,主要是关于底层是Android系统的)为了防止这种情况的发生,我们可以有以下两种做法

1 根据Activity的生命周期来控制Mediaplayer

@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();mediaplayer.release();mediaplayer = null;endtongbu = false;startService(new Intent(action));Log.i(TAG, "guanbi");}

2 使用Service后台服务组件,把Mediaplayer类写在Service中(推荐使用这种类型,当把程序关掉后,音乐任然在进行,在后台,有源代码),主要分为四个步骤:

2.1 Service的配置(在配置文件中)

                                                                 
MusicService为继承Service的类

2.2 Service中方法的覆盖

继承Servcie后通常会产生OnBind(),OnCreate(),OnStartCommand方法,通常当startService后,就会运行OnCreate()方法,然后是OnStartCommand()方法,之后如果再运行Service的话,就只运行OnStartCommand的方法,OnCreate()方法只在先前运行一次,除非stopService后,再startService后才执行OnCreate()方法,获取从Activity传过来的值是在OnStartCommand方法中获取

2.3 Activity与Service交互

2.3.1与普通的Activity与Activity之间的交互相同,通过Intent来进行数据的传递(Activity向Service传递数据)

  @Override public void onClick(View v) { // TODO Auto-generated method stub       switch (v.getId()) { case R.id.start:         Bundle  bundle = new Bundle();         bundle.putSerializable("start", "start");                  startService(new Intent(action).putExtras(bundle));         receivewholetime = true;              break; case R.id.pause:      Bundle  bundle1= new Bundle();        bundle1.putSerializable("start", "pause");     startService(new Intent(action).putExtras( bundle1));          break;       case R.id.stop:            Bundle  bundle2 = new Bundle();            bundle2.putSerializable("start", "stop");            startService(new Intent(action).putExtras(bundle2));                      break; } }
2.3.2 Service获取Activity传过来的数据(Service获取数据通常在OnStartCommand的方法中)

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// TODO Auto-generated method stub               Log.i(TAG, "sererere");      judgefunction = (String)intent.getExtras().getSerializable("start");if(judgefunction.equals("start")){  try {bofang(); endtongbu = true;startthread = true;if(startthread){new Thread(new tongbu()).start();startthread = false;}} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(judgefunction.equals("pause")){     zanting();}if(judgefunction.equals("stop")){ tingzhi();}return super.onStartCommand(intent, flags, startId);}

2.4 Service与Activity交互(有很多种方法,在此使用BroadCast广播类方法)

2.4.1注册广播接收

 //注册广播接收    receiver = new MyReceiver();    IntentFilter  filter = new IntentFilter();    filter.addAction(action);    SurfaceFunction.this.registerReceiver(receiver, filter);
2.4.2接收广播(Activity获取Service传递过来的数据)

 public     class  MyReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {// TODO Auto-generated method stub      if(receivewholetime){      int  time = intent.getExtras().getInt("wholetime");      longshijian1 = new haomiaotoshijian().formattime(time);  //歌曲总时间转换格式      Log.i(TAG, "总时间" + longshijian1);      wholetime.setText(longshijian1);      seekbar.setMax(time);      receivewholetime = false;      }                int progress = (int)intent.getExtras().getInt("progress");      seekbar.setProgress(progress);      String currenttimeone = new haomiaotoshijian().formattime(progress);      currenttime.setText(currenttimeone);              }  }
2.4.3发送广播(Service向Activity发送数据)

 //发送广播        Intent intent=new Intent();        intent.putExtra("wholetime", longshijian);        intent.setAction("com.example.testboke.MusicService");        sendBroadcast(intent);
上述就是完整的步骤,希望大家也可以给出我建议,以Service形式的mini音频播放器源代码地址:http://download.csdn.net/detail/danielntz/9575869

有一些功能我自己就没有实现了,比如进度条控制的快进快退,有兴趣的同学可以自己试着写,这个代码运行后,关闭了程序后,音乐还在播放,如果想停止,就在你需要停止的地方添加stopService方法即可







 

 

 

 

 

 

 

 

 

      

 

更多相关文章

  1. 电池驱动调试总结,电池服务+电量计驱动+调试方法
  2. Android应用程序通用自动脱壳方法研究
  3. Android中Webview与原生界面交互及二维码扫描功能实现
  4. android下创建文件夹和修改其权限的方法
  5. Android X86强制竖屏怎么办?安卓(Android)x86屏幕旋转成横屏解决
  6. android客户端和网站数据交互的实现(基于Http协议获取数据方法)
  7. Andoid自动判断输入是电话,网址或者Email的方法----Linkify的应
  8. Android网络功能之会话发起协议SIP

随机推荐

  1. Android+Jquery Mobile学习系列(1)-开发
  2. Android应用开发资源
  3. App 开发 Android Fragments 的详细使用
  4. Android(安卓)OpenGL ES(九):绘制线段Line
  5. Android最佳实践之:代码性能优化——Stric
  6. [置顶] Android应用程序签名
  7. Android将后台应用唤起到前台,唤醒APP;
  8. [置顶] Android camera子系统HAL层介绍集
  9. Android应用数字签名详解
  10. android桌面画面循环滑动