Android最简单音乐播放器的小例子总结

这只是一个小例子,实现三首mp3格式音乐的循环播放,并且有播放、暂停、停止的功能。

大体思想:

  1. 需要一个Activity用来与用户交互当前播放情况,用户通过点击按钮操作播放、暂停和停止。

  2. 还需要有一个后台Service处理音乐的播放(还好Android有MediaPlayer对象可以对音乐进行播放、暂停等操作)。

  3. Activity和Service之间需要进行交互,

    (1)用户点击按钮执行音乐的播放、暂停或者停止,每一个按钮对应一种状态,通过Broadcast广播传给Service。

    (2)Service接收Activity发来的广播,对操作进行判断从而执行MediaPlayer的音乐操作。之后将音乐的信息同样以广播的形式发送回Activity。

    (3)Activity接收Service的广播在页面上更新歌曲的信息。

下面是细节的问题:

1.首先Activity布局非常简单,一个文本框用来显示歌曲名,两个按钮,“播放”和“停止”。

2.然后是Activity:

(1)onCreate()方法:

    这是Activity第一次创建的时候调用的,因此默认代码就是将布局文件进行加载。除了这些内容,我们要获取获取布局文件上的组件,尤其是Button,我们需要定义监听器处理用户点击的事件(一会就会说到)。其实最主要的两件事是创建BroadcastReceiver对象、Intent过滤器和Receiver的注册(Broadcast不同于监听器,Broadcast是一个系统级的监听器,拥有自己的进程,因此只要存在与之匹配的Intent被广播出来,BroadcastReceiver总会被触发),然后开启后台的Service。

ar = new ActivityReceiver();

IntentFilter filter = new IntentFilter();

filter.addAction(UPDATE_ACTION); //update更改界面播放信息

getApplicationContext().registerReceiver(ar,filter);

Intent in = new Intent(MainActivity.this,MP3Service.class);

startService(in); //开启Service

 

(2)定义BroadcastReceiver的子类并重写onReceive方法,这是Service发送歌曲信息的广播,然后Activity获取并更新页面的Receiver:onReceive方法在应用发送相应广播后自动执行,执行之后BroadcastReceiver实例就会被销毁。

public class ActivityReceiver extends BroadcastReceiver{

  

        @Override

        public void onReceive(Context context, Intent intent) {

            System.out.println("activity receive");

            int update = intent.getIntExtra("update", -1);

            int current = intent.getIntExtra("current", -1);

            if(current>=0){

                title.setText(titleStrs[current]);

            }

            switch(update){

            case 0x11:

                play.setText(R.string.play);

                break;

            case 0x12:

                play.setText(R.string.pause);

                break;

            case 0x13:

                play.setText(R.string.play);

                break;

            }

        }

          

    }

 

(3)onClick:首先Activity有两个按钮,定义一个control状态代表哪个按钮被执行,播放和暂停是一类的,停止是第二类的,将哪个按钮被执行的control状态封装到Intent中,然后发送广播给Service。

public void onClick(View source) {

    Intent in = new Intent(CTL_ACTION); //Service中广播处理的是CTL_ACTION的Intent

    switch(source.getId()){

    case R.id.play:

        in.putExtra("control", 1);

        break;

    case R.id.stop:

        in.putExtra("control", 2);

        break;

    }

    sendBroadcast(in);//发送广播到service

    System.out.println("activity send");

}

 

(4)onDestroy:最后,因为Service是Activity开启的,而且同样在onCreate中注册了BroadcastReceiver,因此当Activity被销毁时,也需要将Service和BroadcastReceiver释放:

protected void onDestroy() {

    stopService(in);

    getApplicationContext().unregisterReceiver(ar);

    super.onDestroy();

}

3.接着是Service:

(1)onCreate:创建MediaPlayer对象,为MediaPlayer设置CompletingListener监听器(当前数据被播放完之后执行,用来播放下一首),创建AssetManager对象用于读取sdcard的音乐文件,并创建接收Activity广播的BroadcastReceiver:

asset = getAssets();

mr = new MyReceiver();

IntentFilter filter = new IntentFilter(MainActivity.CTL_ACTION); //控制播放

getApplicationContext().registerReceiver(mr,filter);

mp = new MediaPlayer();

 

(2)MediaPlayer的监听器:根据current当前歌曲的标号进行歌曲的切换,并发送下一首歌曲的信息通过广播发送给Activity:

mp.setOnCompletionListener(new OnCompletionListener(){

  

            @Override

            public void onCompletion(MediaPlayer mp) {

                current = current+1; //从0开始的,0,1,2三首

                if(current>=3){

                    current = 0;

                }

                //通知界面更新歌曲信息

                Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);

                sendIntent.putExtra("current", current);

                sendBroadcast(sendIntent);

                prepareAndPlay(songs[current]);

            }

              

        });

 

(3)最重要的接收Activity中用户点击按钮的状态发来的广播进行音乐播放处理的Receiver:

public class MyReceiver extends BroadcastReceiver{

  

        @Override

        public void onReceive(Context context, Intent intent) {

            System.out.println("serivce receive");

            int control = intent.getIntExtra("control",-1);

            switch(control){

            case 1: //播放或暂停

                if(status==0x11){

                    prepareAndPlay(songs[current]);

                    status = 0x12;

                }

                else if(status==0x12){

                    mp.pause();

                    status = 0x13;

                }

                else if(status==0x13){

                    mp.start();

                    status = 0x12;

                }

                break;

            case 2: //停止音乐

                if(status==0x12||status==0x13){

                    mp.stop();

                    status = 0x11;

                }

            }

            Intent sendIntent = new Intent(MainActivity.UPDATE_ACTION);

            sendIntent.putExtra("current",current);

            sendIntent.putExtra("update", status);

            sendBroadcast(sendIntent);

            System.out.println("service send");

        }

          

    }

 

(4)最后在onDestroy中释放Receiver:

public void onDestroy() {

        System.out.println("ondestroy");

        getApplicationContext().unregisterReceiver(mr);

        super.onDestroy();

    }

(5)有一个细节,就是在播放完一个歌曲之后,再播放下一个的时候,MediaPlayer对象一定要执行reset方法,不然会发生MediaPlayer状态的异常。以下是prepareAndPlay方法:

 

public void prepareAndPlay(String music){

        try{

            File f = new File(Environment.getExternalStorageDirectory()+"/"+music);

            if(f.exists()){

                System.out.println("--cunzai--");

            }

            //AssetFileDescriptor afd = asset.openFd(Environment.getExternalStorageDirectory()+"/"+music);

            try {

                mp.reset(); //在执行新的一次play的时候需要reset

                mp.setDataSource(Environment.getExternalStorageDirectory()+"/"+music);

                mp.prepare();

                mp.start();

            } catch (IllegalArgumentException e) {

                e.printStackTrace();

            } catch (SecurityException e) {

                e.printStackTrace();

            } catch (IllegalStateException e) {

                e.printStackTrace();

            } catch (IOException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        }catch(Exception e){

              

        }

    }

4.最后别忘记在Manifest文件中配置Service,由于Receiver是在代码中生成的,因此无需进行配置。

Android最简单音乐播放器的小例子总结,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。