简易音乐播放器

今天做了一个简易的音乐播放器程序,其实主要是运用一下MediaPlayer。
播放器有两个按钮,分别是播放和暂停;一个textview显示文件总时长;两个seekbar,分别是调节进度和音量大小。
设计思路:
1.运用MediaPlayer加载音乐文件。其中加载文件有好几种方式:
a.将音频文件拷贝到工程目录的文件夹中

mediaPlayer=mediaPlayer.create(this,R.raw.music );

或者

mediaPlayer.setDataSource(this, 
//                   Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.music));

b.从网络资源加载音频文件

mediaPlayer.setDataSource(this, Uri.parse("www.baidu.com/music.mp3"));

c.从sd卡中加载音频文件

String path=Environment.getExternalStorageDirectory().getAbsolutePath()+"/music.mp3";//动态拿到文件
             mediaPlayer.setDataSource(path);//加载sd卡文件

这里注意:如果是用的setDataSource方法,调用这个方法后,音频文件并没有真正装载,而是还需要调用preper方法。细心可以发现,开始播放音频文件之后,即使关闭程序,即跳出activity。音频仍旧还在播放,因为mediaplayer和activity的生命周期无关。所以我们如果要实现跳出activity就关掉音频怎应该重写activity中的onDestroy方法,判断是否还在播放,然后stop。

protected void onDestroy() {//mediaplayer生命周期与activity生命周期无关,所以关闭activity也不会关闭音乐,所以需要重新设置属性
        if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
            mediaPlayer.stop();
            mediaPlayer.reset();//音乐播放涉及到硬件设备所以需要回收资源,变为空闲状态
            mediaPlayer=null;
        }
        super.onDestroy();
    }

其中preper方法也分同步加载和异步加载,分别是:

            mediaPlayer.prepare();//同步加载方式
// mediaPlayer.prepareAsync();//异步加载方式

2.其中mediaplayer还有许多方法,这里用到的是设置播放模式,即循环播放,单曲循环,顺序播放等等;监听事件有出错事件监听和播放完成事件监听等等,播放完成事件监听可以实现播放下一曲的需求。但是播放完成事件监听事件若要实现,则循环模式必定要设置成false即不要单曲循环。

mediaPlayer.setLooping(false);//设置循环播放,true为循环,false不循环
// mediaPlayer.setOnErrorListener(new OnErrorListener() ;//出错事件监听
            mediaPlayer.setOnCompletionListener(new OnCompletionListener() {//1.播放完成监听器,播放完成触发,2.而且不可循环即setlooping为false

                public void onCompletion(MediaPlayer mp) {
                    Toast.makeText(MainActivity.this, "播放下一首", 0).show();
                }
            });

3.将文件总时长获取到并且加载到textview组件中。并且动态的设置进度条的最大值(获取文件的总时长–毫秒)

private void convert() {
        time=mediaPlayer.getDuration()/1000;//得到总得秒数
         mtime=time/60;
         stime=time%60;
    }
    tv.setText(mtime+":"+stime);
jindu.setMax(mediaPlayer.getDuration());//设置进度条最大值,确保音频播放完进度条终止

4.这样音频文件加载成功,我们需要让seekbar进度条跟随文件的播放动起来。并且还能根据调节进度条来改变音频的播放进度。即断点播放。这时候需要用到子线程和handle机制了。
a.首先我们先让进度条跟随音频的播放动起来。在播放按钮的点击事件中,启动播放后,开启一个子线程,在一个循环中每隔1秒给handler发送一个消息。handler接受到消息之后,获取当前音频播放进度,再将其设置为进度条的进度。这样就让进度条随着音频播放动起来了。

    private Handler handler=new Handler(){
        //收到handler发回的消息时候回调
        public void handleMessage(android.os.Message msg) {
            if(msg.what==0x123){
                jindu.setProgress(mediaPlayer.getCurrentPosition());
            }
        };
    };
    public void start(View view){
        mediaPlayer.start();
        new Thread(){
            public void run() {
                while(true){
                    handler.sendEmptyMessage(0x123);
                    try {
                        sleep(1000);//歌曲是一秒一秒播放,进度条也是这样走
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
        }.start();

    }

b.进度条随着音频的播放动起来,接下来实现音频的播放会随着进度条的调节而发生改变。即断点播放。此时需要给播放进度条设置点击事件:获取当前的进度条的进度,再 将其值赋给音频播放进度,从而使得音频随着进度条而发生改变。seekbar的点击事件中有三个方法,分别是触摸滑动停止,触摸滑动状态,触摸滑动开始。我需要的是在调节结束后音频会在我们抬手的地方开始播放,所以我们在触摸停止方法中实现。

     jindu.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            public void onStopTrackingTouch(SeekBar seekBar) {
                mediaPlayer.seekTo(jindu.getProgress());
            }

            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
            }
        });

这样我们就实现了音频播放会随着进度条的改变而改变。
5.接下来还有调节音量的功能,此时用到的是一个AudioManger这个类,同样的,我们会对其设置一个最大值,确保音量不会无限增加。有方法可以获得当前系统所有的最大音量值。其中还有一个steamType参数表示的是音量类型,例如通话声音,系统声音,铃声声音等等,这我们选择铃声声音。当然我们还需要设置播放的初始音量,可以通过方法获得当前设备的音量。初始化好之后,我们队音量的seekbar设置点击事件:而此时和进度不一样的是,我们在调节过程中,可以明显感受到音量随着seekbar的改变而发生高低,所以这里我们选择在触摸状态发生改变方法中实现:

    audioManager=(AudioManager) getSystemService(AUDIO_SERVICE);
            yinliang.setMax(audioManager.getStreamMaxVolume(audioManager.STREAM_MUSIC));//获取设备最大音量,参数streamType是音量类型,例如通话声音,系统声音,铃声声音
            yinliang.setProgress(audioManager.getStreamVolume(audioManager.STREAM_MUSIC));//设置初始音量
            yinliang.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

                public void onStopTrackingTouch(SeekBar seekBar) {

                }

                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                public void onProgressChanged(SeekBar seekBar, int progress,
                        boolean fromUser) {
                    audioManager.setStreamVolume(audioManager.STREAM_MUSIC, progress, audioManager.FLAG_SHOW_UI);//第三个参数表示调节是否有ui交互界面出现
                }
            });

这样一个简单的音频播放器就实现了,后期加上ui设计和添加需求会是的使用体验更好。
简易音乐播放器_第1张图片
全部源码:
Mainactivity.class

public class MainActivity extends Activity {

    private int time,mtime,stime;
    private MediaPlayer mediaPlayer;
    private SeekBar jindu,yinliang;
    private TextView tv;
    private AudioManager audioManager;
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        jindu=(SeekBar) findViewById(R.id.jindu);
        yinliang=(SeekBar) findViewById(R.id.yinliang);
        tv=(TextView) findViewById(R.id.tv);
        //实例了一个mediaplayer,并且装载了音乐
        //mediaPlayer=mediaPlayer.create(this,R.raw.music );
         mediaPlayer=new MediaPlayer();
         try {
// mediaPlayer.setDataSource(this, 
// Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.music));
// mediaPlayer.setDataSource(this, Uri.parse("www.baidu.com/music.mp3"));//从网络资源加载

             String path=Environment.getExternalStorageDirectory().getAbsolutePath()+"/music.mp3";//动态拿到文件
             mediaPlayer.setDataSource(path);//加载sd卡文件

            //如果是setDataSource需要调用完这个方法之后,音频文件并没有真正的真正装载,而是要调用preper方法
            mediaPlayer.prepare();//同步加载方式
// mediaPlayer.prepareAsync();//异步加载方式
            mediaPlayer.setLooping(false);//设置循环播放,true为循环,false不循环
// mediaPlayer.setOnErrorListener(new OnErrorListener() ;//出错事件监听
            mediaPlayer.setOnCompletionListener(new OnCompletionListener() {//1.播放完成监听器,播放完成触发,2.而且不可循环即setlooping为false

                public void onCompletion(MediaPlayer mp) {
                    Toast.makeText(MainActivity.this, "播放下一首", 0).show();
                }
            });


            audioManager=(AudioManager) getSystemService(AUDIO_SERVICE);
            yinliang.setMax(audioManager.getStreamMaxVolume(audioManager.STREAM_MUSIC));//获取设备最大音量,参数streamType是音量类型,例如通话声音,系统声音,铃声声音
            yinliang.setProgress(audioManager.getStreamVolume(audioManager.STREAM_MUSIC));//设置初始音量
            yinliang.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

                public void onStopTrackingTouch(SeekBar seekBar) {

                }

                public void onStartTrackingTouch(SeekBar seekBar) {

                }

                public void onProgressChanged(SeekBar seekBar, int progress,
                        boolean fromUser) {
                    audioManager.setStreamVolume(audioManager.STREAM_MUSIC, progress, audioManager.FLAG_SHOW_UI);
                }
            });
            // mediaPlayer.prepareAsync();//异步加载方式
        } catch (Exception e) {
            e.printStackTrace();
        } 
         convert();
         tv.setText(mtime+":"+stime);
         jindu.setMax(mediaPlayer.getDuration());

         jindu.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            public void onStopTrackingTouch(SeekBar seekBar) {
                mediaPlayer.seekTo(jindu.getProgress());
            }

            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            public void onProgressChanged(SeekBar seekBar, int progress,
                    boolean fromUser) {
            }
        });

    }

    private void convert() {
        time=mediaPlayer.getDuration()/1000;//得到总得秒数
         mtime=time/60;
         stime=time%60;
    }

    protected void onDestroy() {//mediaplayer生命周期与activity生命周期无关,所以关闭activity也不会关闭音乐,所以需要重新设置属性
        if(mediaPlayer!=null&&mediaPlayer.isPlaying()){
            mediaPlayer.stop();
            mediaPlayer.reset();//音乐播放涉及到硬件设备所以需要回收资源,变为空闲状态
            mediaPlayer=null;
        }
        super.onDestroy();
    }
    private Handler handler=new Handler(){
        //收到handler发回的消息时候回调
        public void handleMessage(android.os.Message msg) {
            if(msg.what==0x123){
                jindu.setProgress(mediaPlayer.getCurrentPosition());
            }
        };
    };
    public void start(View view){
        mediaPlayer.start();
        new Thread(){
            public void run() {
                while(true){
                    handler.sendEmptyMessage(0x123);
                    try {
                        sleep(1000);//歌曲是一秒一秒播放,进度条也是这样走
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
        }.start();

    }
    public void pause(View view){
        mediaPlayer.pause();
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.verney.music.MainActivity" android:orientation="vertical">
    <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="start" android:text="播放"/>
    <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="pause" android:text="暂停"/>

        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv"/>
        <SeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/jindu"/>


    <SeekBar android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/yinliang"/>
</LinearLayout>

你可能感兴趣的:(android,音乐)