在Activity里调用Service中的方法以及MediaPlay类的使用

写了个比较简单的音乐播放器用来练习一下Service的使用方法,以及Android系统内置的多媒体播放的类MediaPlay的使用方法。
下面看一下程序的运行效果:

这里写图片描述

下面直接贴源码:

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private MusicService.MyBinder binder;
    private Myconn conn;
    private static SeekBar mSeekBar;
    private static TextView textViewCurrent;
    private static TextView textViewTotal;

    //使用mHandler接收从Service发回的歌曲播放的当前进度与总进度
    public static Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int current =  msg.getData().getInt("current");
            int total = msg.getData().getInt("total");
            textViewCurrent.setText(getTime(current));
            textViewTotal.setText(getTime(total));
            mSeekBar.setMax(total);
            mSeekBar.setProgress(current);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSeekBar = (SeekBar) findViewById(R.id.seekBar);
        textViewCurrent = (TextView) findViewById(R.id.textview_current);
        textViewTotal = (TextView) findViewById(R.id.textview_total);
        Intent intent = new Intent(this,MusicService.class);
        conn = new Myconn();
        bindService(intent, conn,BIND_AUTO_CREATE);
        //设置SeekBar的监听
        mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
               int currentProgress  =  seekBar.getProgress();
                textViewCurrent.setText(getTime(currentProgress));
                binder.callSetMusicPosition(currentProgress);
            }
        });
    }

    //开始播放
    public void clickPlay(View v){
        binder.callPlayMusic();
    }

    //暂停播放
    public void clickPause(View v){
        binder.callPauseMusic();
    }

    //继续播放
    public void clickStart(View v){
        binder.callStartMusic();
    }
    //当Activity销毁的时候接触与服务的绑定
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解绑服务
        unbindService(conn);
    }

    //实现ServiceConnectionj实现实接口
    private class Myconn implements ServiceConnection{
        //Activity与Service成功绑定的时候调用
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //获取Service中创建的Binder对象
            binder = (MusicService.MyBinder) iBinder;
        }
        //Activity与Service断开连接的时候调用
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i("wk","断开连接了");
        }
    }
    //时间转换
    private static String getTime(int total) {
        SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
        Date date= new Date(total);
        return sdf.format(date);
    }
}

MusicService.java

/**
 * Created by wangke on 2017/2/19.
 */

public class MusicService extends Service {
    private MediaPlayer mediaPlayer;
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //将Binder的实现类返回
        return new MyBinder();
    }
    //Service创建时调用
    @Override
    public void onCreate() {
        super.onCreate();
        String Path = Environment.getExternalStorageDirectory().toString();
        mediaPlayer = new MediaPlayer();
        try {
            mediaPlayer.setDataSource(Path + "/misc.mp3");
            mediaPlayer.prepare();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }

        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                Message msg = Message.obtain();
                Bundle bundle = new Bundle();
                bundle.putInt("current",mediaPlayer.getCurrentPosition());
                bundle.putInt("total",mediaPlayer.getDuration());
                msg.setData(bundle);
                MainActivity.mHandler.sendMessage(msg);

            }
        },100,1000);
    }

    //在每次服务启动的时候调用
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //释放播放器资源
        mediaPlayer.release();
    }

    //开始播放音乐
    public void playMusic() {
        mediaPlayer.start();
        Toast.makeText(getApplicationContext(), "开始播放音乐", Toast.LENGTH_SHORT).show();
    }

    //暂停播放音乐
    public void pauseMusic() {
        if(mediaPlayer.isPlaying()){
            mediaPlayer.pause();
        }
        Toast.makeText(getApplicationContext(), "暂停播放音乐", Toast.LENGTH_SHORT).show();

    }

    //继续播放音乐
    public void startMusic() {

        if(!mediaPlayer.isPlaying()){
            mediaPlayer.start();
        }
        Toast.makeText(getApplicationContext(), "继续播放音乐", Toast.LENGTH_SHORT).show();
    }


    private void setMusicPosition(int position) {
        mediaPlayer.seekTo(position);
    }
    //创建Binder的实现类,在里面创建需要在Activity中调用的方法
    public class MyBinder extends Binder {
        public void callPlayMusic() {
            playMusic();
        }
        public void callPauseMusic() {
            pauseMusic();
        }
        public void callStartMusic() {
            startMusic();
        }
        public void callSetMusicPosition(int position){
            setMusicPosition(position);
        }
    }

}

下面回顾下Service的相关知识:

startService方法开启服务的特点:

  • 服务通过startService的方式开启,第一次点击按钮开启服务器,会执行服务的onCreate 和 onStart方法。
  • 第二次点击按钮开启服务后只会执行 onStartCommand方法

bindService 方式开启服务的特点

  • 当点击按钮第一次开启服务会执行服务的onCreate方法 和 onBind()方法
  • 当第二次点击按钮在调用bindservice 服务没有响应
  • 当Activity销毁的时候服务也跟着销毁
  • bindService不能多次解除绑定否则会报错

    因此实现在后台播放音乐的功能还需要使用混合模式来开启一个服务,在bindService前使用startService方法开启服务。

下面简单梳理一下在Activity中使用bindservice方式调用服务里的方法的几个过程(拿上面Demo为例):

(1):创建一个服务,并在里面声明需要Activity进行调用的方法

 //开始播放音乐
    public void playMusic() {
        mediaPlayer.start();
        Toast.makeText(getApplicationContext(), "开始播放音乐", Toast.LENGTH_SHORT).show();
    }
    //暂停播放音乐
    public void pauseMusic() {
        if(mediaPlayer.isPlaying()){
            mediaPlayer.pause();
        }

        Toast.makeText(getApplicationContext(), "暂停播放音乐", Toast.LENGTH_SHORT).show();

    }
    //继续播放音乐
    public void startMusic() {

        if(!mediaPlayer.isPlaying()){
            mediaPlayer.start();
        }
        Toast.makeText(getApplicationContext(), "继续播放音乐", Toast.LENGTH_SHORT).show();
    }
    private void setMusicPosition(int position) {
        mediaPlayer.seekTo(position);
    }

(2):创建Binder的实现类,在里面创建需要在Activity中调用的方法

public class MyBinder extends Binder {
        public void callPlayMusic() {
            playMusic();
        }
        public void callPauseMusic() {
            pauseMusic();
        }

        public void callStartMusic() {
            startMusic();
        }

        public void callSetMusicPosition(int position){
            setMusicPosition(position);
        }
    }

(3):在onBind( )方法中将创建好的Binder对象返回

    @Override
    public IBinder onBind(Intent intent) {
        //将Binder的实现类返回
        return new MyBinder();
    }

(4):在Activity的onCreate( )方法中调用bindService方法来获取在service中定义好的Binder对象

 Intent intent = new Intent(this,MusicService.class);
        conn = new Myconn();
        bindService(intent, conn,BIND_AUTO_CREATE);

(4.1):实现ServiceConnection接口在onServiceConnected方法中获取在Service中定义好的Binder对象

  private class Myconn implements ServiceConnection{
        //Activity与Service成功绑定的时候调用
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //获取Service中创建的Binder对象
            binder = (MusicService.MyBinder) iBinder;
        }
        //Activity与Service断开连接的时候调用
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.i("wk","断开连接了");
        }
    }

(5):获取到Binder对象之后,就可以在相应的事件中调用Service中的相关方法

 //开始播放
    public void clickPlay(View v){
        binder.callPlayMusic();
    }

以上就是在Activity中调用Service中方法的实现过程。


MediaPlay类的相关用法

1.获得MediaPlay实例:

MediaPlayer mediaPlayer = new MediaPlayer();

MediaPlayer mediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.music.mp3)

2.设置播放的文件:

 //设置文件资源的三种来源:
 //1.网络资源
 //2.存储目录中
 //3.当前工程下的res资源
 mediaPlayer.setDataSource(Path + "/misc.mp3");

3.对MediaPlay控制的相关方法:

prepare() //使播放器进入准备状态,如果是使用create方式创建的MediaPlayer内部已经调用,不需要再次调用

start() //进行文件播放的方法

pause() //暂停播放
stop() //停止播放
release() //可以释放播放器占用的资源,一旦确定不再使用播放器时应当尽早调用它释放资源。
reset()可以使播放器从Error状态中恢复过来,重新会到闲置状态。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值