欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android基于Service的音乐播放器

程序员文章站 2024-03-05 17:14:55
本文开发一个基于service的音乐播放器,音乐由后台运行的service负责播放,当后台的播放状态发生变化时,程序将会通过发送广播通知前台activity更新界面;当点击...

本文开发一个基于service的音乐播放器,音乐由后台运行的service负责播放,当后台的播放状态发生变化时,程序将会通过发送广播通知前台activity更新界面;当点击activity的界面按钮时,系统将通过发送广播通知后台service来改变播放状态。

前台activity界面有两个按钮,分别用于控制播放/暂停、停止,另外还有两个文本框,用于显示正在播放的歌曲名、歌手名。前台activity的代码如下:

public class mainactivity extends appcompatactivity implements view.onclicklistener{

  private imagebutton mstart;
  private imagebutton mstop;
  private textview mmusicname;
  private textview msongername;
  private activityreceiver mactivityreceiver;
  public static final string ctl_action = "com.trampcr.action.ctl_action";
  public static final string update_action = "com.trampcr.action.update_action";

  //定义音乐播放状态,0x11代表没有播放,0x12代表正在播放,0x13代表暂停
  int status = 0x11;
  string[] musicnames = new string[]{"完美生活", "那一年", "故乡"};
  string[] songernames = new string[]{"许巍", "许巍", "许巍"};


  @override
  protected void oncreate(bundle savedinstancestate) {
    super.oncreate(savedinstancestate);
    setcontentview(r.layout.activity_main);

    mstart = (imagebutton) findviewbyid(r.id.start);
    mstop = (imagebutton) findviewbyid(r.id.stop);
    mmusicname = (textview) findviewbyid(r.id.music_name);
    msongername = (textview) findviewbyid(r.id.songer_name);

    mstart.setonclicklistener(this);
    mstop.setonclicklistener(this);

    mactivityreceiver = new activityreceiver();
    //创建intentfilter
    intentfilter filter = new intentfilter();
    //指定broadcastreceiver监听的action
    filter.addaction(update_action);
    //注册broadcastreceiver
    registerreceiver(mactivityreceiver, filter);

    intent intent = new intent(mainactivity.this, musicservice.class);
    //启动后台service
    startservice(intent);
  }

  public class activityreceiver extends broadcastreceiver {
    @override
    public void onreceive(context context, intent intent) {
      //获取intent中的update消息,update代表播放状态
      int update = intent.getintextra("update", -1);
      //获取intent中的current消息,current代表当前正在播放的歌曲
      int current = intent.getintextra("current", -1);
      if (current >= 0){
        mmusicname.settext(musicnames[current]);
        msongername.settext(songernames[current]);
      }
      switch (update){
        case 0x11:
          mstart.setbackgroundresource(r.drawable.play);
          status = 0x11;
          break;
        //控制系统进入播放状态
        case 0x12:
          //在播放状态下设置使用暂停图标
          mstart.setbackgroundresource(r.drawable.pause);
          status = 0x12;
          break;
        case 0x13:
          //在暂停状态下设置使用播放图标
          mstart.setbackgroundresource(r.drawable.play);
          status = 0x13;
          break;
      }
    }
  }

  @override
  public void onclick(view v) {
    intent intent = new intent(ctl_action);
    switch (v.getid()){
      case r.id.start:
        intent.putextra("control", 1);
        break;
      case r.id.stop:
        intent.putextra("control", 2);
        break;
    }
    //发送广播,将被service中的broadcastreceiver接收到
    sendbroadcast(intent);
  }
}

activityreceiver()用于响应后台service所发出的广播,该程序将会根据广播intent里的消息来改变播放状态,并更新程序界面中按钮的图标。

onclick中根据点击的按钮发送广播,发送广播时会把所按下的按钮标识发送出来。

接下来是后台service,会在播放状态发生改变时对外发送广播。代码如下:

public class musicservice extends service {

  myreceiver servicereceiver;
  assetmanager massetmanager;
  string[] musics = new string[]{"prefectlife.mp3", "thatyear.mp3", "country.mp3"};
  mediaplayer mmediaplayer;
  int status = 0x11;
  int current = 0; // 记录当前正在播放的音乐

  @nullable
  @override
  public ibinder onbind(intent intent) {
    return null;
  }

  @override
  public void oncreate() {
    super.oncreate();
    massetmanager = getassets();
    servicereceiver = new myreceiver();
    //创建intentfilter
    intentfilter filter = new intentfilter();
    filter.addaction(mainactivity.ctl_action);
    registerreceiver(servicereceiver, filter);
    //创建mediaplayer
    mmediaplayer = new mediaplayer();
    //为mediaplayer播放完成事件绑定监听器
    mmediaplayer.setoncompletionlistener(new mediaplayer.oncompletionlistener() {
      @override
      public void oncompletion(mediaplayer mp) {
        current++;
        if (current >= 3) {
          current = 0;
        }
        //发送广播通知activity更改文本框
        intent sendintent = new intent(mainactivity.update_action);
        sendintent.putextra("current", current);
        //发送广播,将被activity中的broadcastreceiver接收到
        sendbroadcast(sendintent);
        //准备并播放音乐
        prepareandplay(musics[current]);
      }
    });
  }

  public class myreceiver extends broadcastreceiver {
    @override
    public void onreceive(context context, intent intent) {
      int control = intent.getintextra("control", -1);
      switch (control){
        case 1: // 播放或暂停
          //原来处于没有播放状态
          if (status ==0x11){
            //准备播放音乐
            prepareandplay(musics[current]);
            status = 0x12;
          }
          //原来处于播放状态
          else if (status == 0x12){
            //暂停
            mmediaplayer.pause();
            status = 0x13; // 改变为暂停状态
          }
          //原来处于暂停状态
          else if (status == 0x13){
            //播放
            mmediaplayer.start();
            status = 0x12; // 改变状态
          }
          break;
        //停止声音
        case 2:
          //如果原来正在播放或暂停
          if (status == 0x12 || status == 0x13){
            //停止播放
            mmediaplayer.stop();
            status = 0x11;
          }
      }
      //广播通知activity更改图标、文本框
      intent sendintent = new intent(mainactivity.update_action);
      sendintent.putextra("update", status);
      sendintent.putextra("current", current);
      //发送广播,将被activity中的broadcastreceiver接收到
      sendbroadcast(sendintent);
    }
  }

  private void prepareandplay(string music) {
    try {
      //打开指定的音乐文件
      assetfiledescriptor assetfiledescriptor = massetmanager.openfd(music);
      mmediaplayer.reset();
      //使用mediaplayer加载指定的声音文件
      mmediaplayer.setdatasource(assetfiledescriptor.getfiledescriptor(), assetfiledescriptor.getstartoffset(), assetfiledescriptor.getlength());
      mmediaplayer.prepare(); // 准备声音
      mmediaplayer.start(); // 播放
    } catch (ioexception e) {
      e.printstacktrace();
    }
  }
}

myreceiver用于接收前台activity所发出的广播,并根据广播的消息内容改变service的播放状态,当播放状态改变时,该service对外发送一条广播,广播消息将会被前台activity接收,前台activity将会根据广播消息更新界面。

为了让该音乐播放器能按顺序依次播放歌曲,程序为mediaplayer增加了oncompletionlistener监听器,当mediaplayer播放完成后将自动播放下一首歌曲。

运行程序,效果图如下:

Android基于Service的音乐播放器

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。