Android 后台播放音乐Demo

开发流程:

A,创建服务把想使用的方法暴露出来。

B,定义接口,bind调用时返回对象,在service 开启播放音乐实时更新进度条的位置

C,Activity 中创建hander 更新UI

【1】布局

<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:orientation="vertical"

    tools:context=".MainActivity" >



    <Button

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:onClick="click1"

        android:text="播放" />

    

     <Button

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:onClick="click2"

        android:text="暂停" />

     

      <Button

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:onClick="click3"

        android:text="继续播放" />



      <SeekBar

          android:id="@+id/seekBar1"

          android:layout_width="match_parent"

          android:layout_height="wrap_content" />



</LinearLayout>

【2】创建接口

interface Iservice {

//把想暴露的方法定义在接口里

public void callplayMusic();

public void callpauseMusic();

public void callrePlayMusic();

public void callplaySeekToPosition(int position);

}

【3】创建Service 

    A,onCredte 方法中是用MediaPlayer

    B,为了调用Service 里面方法 Bind开启服务,提供Binder 对象 调用里面方法

    C,定义方法,使用Binder的子类暴露出去。

public class MusicService extends Service {

    private Timer timer;

    private TimerTask task;

    private MediaPlayer mediaPlayer;

    //[2]把我们定义的中间人对象返回

    @Override

    public IBinder onBind(Intent intent) {

        return new MyBinder();

    }



    @Override

    public void onCreate() {

        

        //[1]播放sd卡里面的小苹果音乐

        mediaPlayer = new MediaPlayer();

        super.onCreate();

    }

    

    // 播放音乐的方法

    public void playMusic() {

        try {

            //[2]设置播放音乐的路径  设置数据 原:在sd卡

            mediaPlayer.setDataSource("/mnt/sdcard/xpg.mp3");

            //[3]准备播放

            mediaPlayer.prepare();

            //[4]播放音乐

            mediaPlayer.start();

            //[5]歌曲播放的同时 更新进度条

            updateSeekBar();

            

        } catch (Exception e) {

            e.printStackTrace();

        }

    }



    //更新进度条的方法

    private void updateSeekBar() {

        //[1]获取当前歌曲的总时长

        final int duration = mediaPlayer.getDuration();

        //[2]要不停的获取当前歌曲播放的进度  计时器 Timer

        timer = new Timer();

        task = new TimerTask() {

            @Override

            public void run() {

                int currentPosition = mediaPlayer.getCurrentPosition();

                //[3]更新进度条

                Message msg = Message.obtain();

                //[4]准备bundle

                Bundle bundle = new Bundle(); //实际就是map

                bundle.putInt("duration", duration);

                bundle.putInt("currentPosition", currentPosition);

                //[5]使用msg携带多条数据

                msg.setData(bundle);

                //[6]发消息  maniActivity的handlemessage方法就会执行

                MainActivity.handler.sendMessage(msg);

                //[7]给mediaplayer设置播放完成的监听

                mediaPlayer.setOnCompletionListener(new OnCompletionListener() {

                    

                    @Override

                    public void onCompletion(MediaPlayer mp) {

                        System.out.println("歌曲播放完成了");

                        timer.cancel();

                        task.cancel();

                    }

                });

                

                

            }

        };

        //3秒后 执行task  

        timer.schedule(task, 1000,1000);

        

        

    }



    // 暂停音乐的方法

    public void pauseMusic() {

        mediaPlayer.pause();

    }

    // 继续播放音乐的方法

    public void rePlayMusic() {

        //继续播放也是start方法

        mediaPlayer.start();

    }

    

    //设置歌曲播放位置的方法

    public void playSeekToPosition(int position){

        mediaPlayer.seekTo(position);

    }

    

    

    //[1]定义中间人的对象 (IBinder类型)

    private class MyBinder extends Binder implements Iservice{



        @Override

        public void callplayMusic() {

            //调用播放音乐的方法

            playMusic();

        }



        @Override

        public void callpauseMusic() {

            //调用暂停音乐的方法

            pauseMusic();

        }



        @Override

        public void callrePlayMusic() {

            //调用继续播放音乐的方法

            rePlayMusic();

        }



        @Override

        public void callplaySeekToPosition(int position) {

            playSeekToPosition(position);

        }

        

    }

    

    



}



【3】MainActiivty 中调用:     

    A,获取控件,startService 开启服务确保能够在后台长期运行

    B,BindService获取返回的接口对象,调用其中暴露给我们的方法,播放, 暂停。

    C,seekBar.设置位置关联进度。

public class MainActivity extends Activity {

    private Iservice iservice;//我们定义的中间人对象

    private MyConn conn;

    private static SeekBar seekBar;

    

    public static Handler handler = new Handler(){

        //这个方法处理消息的时候执行

        public void handleMessage(android.os.Message msg) {

            //[1]获取发消息携带的数据  数据是怎么发的 就怎么取   数据发的是什么类型就取什么类型

            Bundle data = msg.getData();

            //[2]获取歌曲的总时长和 当前进度

            int duration = data.getInt("duration");

            int currentPosition = data.getInt("currentPosition");

            //[3]更新进度条

            seekBar.setMax(duration);

            seekBar.setProgress(currentPosition);

            

            

        };

    };

    

    

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        

        //[1]调用startservice 保证服务在后台长期运行

        Intent intent = new Intent(this,MusicService.class);

        startService(intent);

        //[2]想点击按钮的时候 调用服务里面的方法  获取我们在服务内部定义的中间人对象

        conn = new MyConn();

        bindService(intent, conn, BIND_AUTO_CREATE);

        

        //[3]找到进度条

        seekBar = (SeekBar) findViewById(R.id.seekBar1);

        //[4]给seekbar设置监听

        seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

            //当拖动进度条停止 执行

            @Override

            public void onStopTrackingTouch(SeekBar seekBar) {

                //在这个方法里面实现拖动到哪就播放歌曲对应的位置

                iservice.callplaySeekToPosition(seekBar.getProgress());

                

            }

            //干开始托

            @Override

            public void onStartTrackingTouch(SeekBar seekBar) {

                

            }

            

            @Override

            public void onProgressChanged(SeekBar seekBar, int progress,

                    boolean fromUser) {

                

            }

        });

        

    }

    

    //监视服务的状态

    private class MyConn implements ServiceConnection {

    

        //当连接服务成功后调用

        @Override

        public void onServiceConnected(ComponentName name, IBinder service) {

            //获取我们定义的中间人对象

            iservice = (Iservice) service;

            

            

        }

        @Override

        public void onServiceDisconnected(ComponentName name) {



        }



    }

    

    @Override

    protected void onDestroy() {

        //当Activity销毁的时候 解绑服务

        unbindService(conn);

        super.onDestroy();

    }



    // 点击按钮实现音乐的播放

    public void click1(View v) {



        iservice.callplayMusic();

    }



    // 点击按钮实现音乐的暂停

    public void click2(View v) {

        iservice.callpauseMusic();



    }



    // 点击按钮实现音乐的继续播放

    public void click3(View v) {

        iservice.callrePlayMusic();

    }



}











猜你喜欢

转载自blog.csdn.net/Cricket_7/article/details/84997357