手机影音第十五天,利用service实现后台播放音乐,在通知栏显示当前音乐信息等

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手机影音第十五天,利用service实现后台播放音乐,在通知栏显示当前音乐信息等相关的知识,希望对你有一定的参考价值。

    代码已经托管到码云上,有兴趣的小伙伴可以下载看看

        https://git.oschina.net/joy_yuan/MobilePlayer


    先来一张目前的音乐播放器的效果图,当播放时,手机的状态通知栏也会有音乐信息显示。

        技术分享



    这里可以看到有歌名、演唱者,还有歌曲的总时间,当前播放时间,当前播放进度,音乐暂停、下一首,上一首,音乐循环模式(单曲循环,顺序播放、循环播放)功能的实现。下一步就是把中间空白的部分填充歌词,然后做成根据进度显示歌词。


    由于这次的内容有点多,是写了一天半的代码,讲的没那么细,具体的代码可以去下载源码看下。


    一、要想做成即使推出播放器后(不是杀死进程),音乐播放器继续播放,那么就不能在activity里进行播放音乐,需要在service里播放音乐

    1、aidl的使用,来连接activity和service。

        这个aidl有点类似service的接口。

        其实用来连接activity和service也可以用内部类IBindler 来做,具体的可以看我前面写的博客,四大组件之service,里面有详细写activity绑定service。

// IMusicPlayerService.aidl
package com.yuanlp.mobileplayer;

// Declare any non-default types here with import statements

interface IMusicPlayerService {
    /**
        * 根据对应位置打开音乐
        * @param position
        */
       void openAudio(int position);

       /**
        * 播放音乐
        */
      void startAudio();

       /**
        * 暂停音乐
        */
       void pauseAudio();

       /**
        * 停止音乐
        */
        void stopAudio();

       /**
        * 得到当前播放进度
        * @return
        */
      int getCurrentPosition();

       /**
        * 得到总时长
        * @return
        */
       long getDuration();

       /**
        * 得到演唱者
        * @return
        */
      String getSinger();

       /**
        * 得到音乐大小
        * @return
        */
       long getSize();
       /**
        * 得到歌名
        * @return
        */
      String getSong();

       /**
        * 得到路径
        * @return
        */
      String getAudioPath();

       /**
        * 得到下一首
        */
        void getNext();
       /**
        * 得到上一首
        */
       void getPre();

       /**
        * 设置播放模式
        * @param playMode
        */
       void setPlayMode(int playMode);

       /**
        * 得到播放模式
        */
      int  getPlayMode();

      /**
      * 是否播放
      */
      boolean isPlaying();

      void seekTo(int progress);
}


    2 、创建service,第一种可以直接写类,然后继承Service,需要手动重写oncreate()和onBind()方法,然后还要在androidManifext.xml里注册这个类;第二种,右键new一个service,这样就不用去重写方法,以及去注册了,因为IDE会自动帮我们做好。

        

package com.yuanlp.mobileplayer.service;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.RequiresApi;
import android.util.Log;

import com.yuanlp.mobileplayer.IMusicPlayerService;
import com.yuanlp.mobileplayer.R;
import com.yuanlp.mobileplayer.activity.AudioPlayerAcivity;
import com.yuanlp.mobileplayer.bean.MediaItem;
import com.yuanlp.mobileplayer.utils.CacheUtils;

import java.io.IOException;
import java.util.ArrayList;

public class MusicPlayerService extends Service {
    private static final String TAG = "MusicPlayerService";
    public static final String OPENAUDIOPLAYER = "com.yuanlp.mobilePlayer_openAudioPlayer";

    private int position;
    private ArrayList<MediaItem> medialist;
    private MediaItem item;
    private MediaPlayer mediaPlayer;
    private NotificationManager manger;  //状态栏通知管理器

    public static final int REPEAT_NORMAL=1;  //默认播放模式,即顺序播放
    public static final int REPEAT_SINGLE=2;  //单曲循环
    public static final int REPEAT_ALL=3;  //循环播放




    private int playMode=REPEAT_NORMAL;  //播放模式


    public MusicPlayerService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        
        playMode=CacheUtils.getPlayMode(this,"playmode");
    }


    /**
    *    在这里获取aidl的实例,需要在onBind()方法里返回这个实例。onBind()方法在activity
    与service绑定时自动调用。
    **/
    private IMusicPlayerService.Stub stub=new IMusicPlayerService.Stub() {

        MusicPlayerService service=MusicPlayerService.this;
        @Override
        public void openAudio(int position) throws RemoteException {
            System.out.println("调取了内部的方法传递position为"+position);
            service.openAudio(position);
        }

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public void startAudio() throws RemoteException {
            service.startAudio();
        }

        @Override
        public void pauseAudio() throws RemoteException {
            service.pauseAudio();
        }

        @Override
        public void stopAudio() throws RemoteException {
            service.stopAudio();
        }

        @Override
        public int getCurrentPosition() throws RemoteException {
            return service.getCurrentPosition();
        }

        @Override
        public long getDuration() throws RemoteException {
            return service.getDuration();
        }

        @Override
        public String getSinger() throws RemoteException {
            return service.getSinger();
        }

        @Override
        public long getSize() throws RemoteException {
            return service.getSize();
        }

        @Override
        public String getSong() throws RemoteException {
            return service.getSong();
        }

        @Override
        public String getAudioPath() throws RemoteException {
            return service.getAudioPath();
        }

        @Override
        public void getNext() throws RemoteException {
            service.getNext();
        }

        @Override
        public void getPre() throws RemoteException {
            service.getPre();
        }

        @Override
        public void setPlayMode(int playMode) throws RemoteException {
            service.setPlayMode(playMode);
        }

        @Override
        public int getPlayMode() throws RemoteException {
            return service.getPlayMode();
        }

        /**
         * 是否播放
         */
        @Override
        public boolean isPlaying() throws RemoteException {
            return service.isPlaying();
        }
        //把进度条调整到progress的位置
        public void seekTo(int progress){
            service.seekTo(progress);

        }
    };

//  public class Mybinder extends Binder{
//      public MusicPlayerService getService(){
//          return MusicPlayerService.this;
//      }
//  }
//
//  public Mybinder binder=new Mybinder();
//    @Override
//    public IBinder onBind(Intent intent) {
//
//        return binder;
//
//    }

    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("绑定了服务------------");

        //当绑定时,获取activity通过intent传过来的序列化的list数据。
       medialist= (ArrayList<MediaItem>) intent.getSerializableExtra("medialist");
       System.out.println("获取服务里的数据。。。"+medialist.size());
        return stub;

    }

    /**
     * 根据对应位置打开音乐
     * @param position
     */
    private void openAudio(int position){
        this.position=position;
        Log.d(TAG, "openAudio:当前位置 "+position);
       item=medialist.get(position);
        Log.d(TAG, "openAudio: 当前位置对应的歌名"+item.getName());

        if (mediaPlayer!=null){
           mediaPlayer.reset();
            mediaPlayer=null;
        }

        try {
            mediaPlayer=new MediaPlayer();
             mediaPlayer.setOnPreparedListener(new MyOnPreparedListener());
            mediaPlayer.setOnCompletionListener(new MyOnCompletionListener());
            mediaPlayer.setOnErrorListener(new MyOnErrorListener());
            mediaPlayer.setDataSource(item.getData());
            mediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 播放出错时回调
     */
    class MyOnErrorListener implements MediaPlayer.OnErrorListener {

        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            getNext();
            return true;
        }
    }
    /**
     * 播放完成时
     */
    class MyOnCompletionListener implements MediaPlayer.OnCompletionListener {


        @Override
        public void onCompletion(MediaPlayer mp) {
            getNext();
        }
    }
    /**
     * 准备好播放时回调
     */
    class MyOnPreparedListener implements MediaPlayer.OnPreparedListener {




        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public void onPrepared(MediaPlayer mp) {
           startAudio();
            //在这里发送广播,通知activity,播放的进度、音乐名称、歌唱家等信息
            notifyChange(OPENAUDIOPLAYER);
        }
    }

    /**
     * 发送广播通知activity
     * @param openaudioplayer
     */
    private void notifyChange(String openaudioplayer) {
        Intent intent=new Intent(openaudioplayer);
        sendBroadcast(intent);
    }

    /**
     * 播放音乐
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void startAudio(){
        mediaPlayer.start();
        manger= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);  //获取系统的通知服务
        //Notification notifaction= null;
            Intent intent=new Intent(this, AudioPlayerAcivity.class);  //点击通知栏后,打开activity音乐界面
            Bundle bundle=new Bundle();
            bundle.putSerializable("mediallist",medialist);
            intent.putExtras(bundle); //把list数据回传给activity,不然会报错
            intent.putExtra("Notifaction",true);  //标识来自状态
            PendingIntent pendingintent=PendingIntent.getActivity(this,1,intent,PendingIntent.FLAG_UPDATE_CURRENT);
            Notification notifaction = new Notification.Builder(this)
                    .setSmallIcon(R.drawable.notification_music_playing)
                    .setContentTitle("原立鹏音乐播放器")  //状态通知栏标题
                    .setContentText("正在播放:"+getSong())  //状态通知栏内容
                    .setContentIntent(pendingintent)
                    .build();  //这个一定要写最后面,不然会出错

        manger.notify(1,notifaction);  //显示状态栏

    }

    /**
     * 暂停音乐
     */
    public void pauseAudio(){
        mediaPlayer.pause();

        //停止播放时取消状态栏
        manger.cancel(1);
    }

    /**
     * 停止音乐
     */
    public void stopAudio(){
        mediaPlayer.stop();
    }

    /**
     * 得到当前播放进度
     * @return
     */
    public int getCurrentPosition(){

        return mediaPlayer.getCurrentPosition();
    }

    /**
     * 得到总时长
     * @return
     */
    public long getDuration(){

        return mediaPlayer.getDuration();
    }

    /**
     * 得到演唱者
     * @return
     */
    public String getSinger(){

        return item.getArtist();
    }

    /**
     * 得到音乐大小
     * @return
     */
    public long getSize(){

        return item.getSize();
    }

    /**
     * 得到歌名
     * @return
     */
    public String getSong(){

        return item.getName();
    }

    /**
     * 得到路径
     * @return
     */
    public String getAudioPath(){

        return item.getData();
    }

    /**
     * 得到下一首
     */
    public void getNext(){

    }

    /**
     * 得到上一首
     */
    public void getPre(){


    }

    /**
     * 设置播放模式,并将播放模式写到sharepreferences里,记忆用户播放模式
     * @param playMode
     */
    public void setPlayMode(int playMode){
        this.playMode=playMode;
        CacheUtils.putPlayMode(this,"playmode",playMode);
    }

    /**
     * 得到播放模式
     */
    public int getPlayMode(){
        return playMode;
    }

    public boolean isPlaying(){
        return mediaPlayer.isPlaying();
    }

    public void seekTo(int progress){
        mediaPlayer.seekTo(progress);
    }
}


二、在activity里,接收audiopager传过来的list数据,并绑定服务,在绑定服务时,通过intent将list数据传给service;在开始播放音乐时,接收service发出的广播,来更新页面显示的歌名、时间等信息,并在handler里每秒刷新下时间。

    

package com.yuanlp.mobileplayer.activity;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.yuanlp.mobileplayer.IMusicPlayerService;
import com.yuanlp.mobileplayer.R;
import com.yuanlp.mobileplayer.bean.MediaItem;
import com.yuanlp.mobileplayer.service.MusicPlayerService;
import com.yuanlp.mobileplayer.utils.Utils;

import java.util.ArrayList;

import static android.content.ContentValues.TAG;

/**
 * Created by 原立鹏 on 2017/7/27.
 */

public class AudioPlayerAcivity extends Activity implements View.OnClickListener {

    private static final int UPDATE_SEEKBAR = 0;  //更新进度条时的handler消息
    private ImageView iv_play_icon;
    private int position;  //获取从audiopager中从intent传过来的位置信息
    private ArrayList<MediaItem> medialist;

    private IMusicPlayerService mservice;

    private ImageView ivPlayIcon;
    private TextView tvSigner;
    private TextView tvSong;
    private TextView tvTime;
    private SeekBar seekbarAudio;
    private Button btAudioMode;
    private Button btAudioPre;
    private Button btAudiostartPause;
    private Button btAudioNext;
    private Button btLyrc;

    private boolean isPlaying;

    private MyBroadcast broadcast; //广播类实例



    private Utils utils;
    private boolean isNotifaction;  //判断是否是从notifaction那里传过来的intent
    private int currentposition;

    /**
     * Find the Views in the layout<br />
     * <br />
     * Auto-created on 2017-07-28 08:54:55 by Android Layout Finder
     * (http://www.buzzingandroid.com/tools/android-layout-finder)
     */
    private void findViews() {
        System.out.println("初始化数据");
        ivPlayIcon = (ImageView)findViewById( R.id.iv_play_icon );
        tvSigner = (TextView)findViewById( R.id.tv_signer );
        tvSong = (TextView)findViewById( R.id.tv_song );
        tvTime = (TextView)findViewById( R.id.tv_time );
        seekbarAudio = (SeekBar)findViewById( R.id.seekbar_audio );
        btAudioMode = (Button)findViewById( R.id.bt_audio_mode );
        btAudioPre = (Button)findViewById( R.id.bt_audio_pre );
        btAudioStartPause = (Button)findViewById( R.id.bt_audio_start_pause );
        btAudioNext = (Button)findViewById( R.id.bt_audio_next );
        btLyrc = (Button)findViewById( R.id.bt_lyrc );

        btAudioMode.setOnClickListener( this );
        btAudioPre.setOnClickListener( this );
        btAudioStartPause.setOnClickListener( this );
        btAudioNext.setOnClickListener( this );
        btLyrc.setOnClickListener( this );
    }

    /**
     * Handle button click events<br />
     * <br />
     * Auto-created on 2017-07-28 08:54:55 by Android Layout Finder
     * (http://www.buzzingandroid.com/tools/android-layout-finder)
     */
    @Override
    public void onClick(View v) {
        if ( v == btAudioMode ) {
            // Handle clicks for btAudioMode
            getPlayMode();  //设置播放模式
        } else if ( v == btAudioPre ) {
            // Handle clicks for btAudioPre
            position-=1;
            if (position<0){
                position=medialist.size()-1;
            }
            try {
                MediaItem item=medialist.get(position);
                tvSigner.setText(item.getArtist());
                tvSong.setText(item.getName());
                mservice.openAudio(position);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if ( v == btAudioStartPause ) {

            try {
                isPlaying=mservice.isPlaying();
                if (isPlaying){  //表示此时在播放,应该把图片切换为播放界面,然后暂停播放
                    mservice.pauseAudio();
                    btAudioStartPause.setBackgroundResource(R.drawable.bt_audio_start_selector);

                }else{
                    mservice.startAudio();
                    btAudioStartPause.setBackgroundResource(R.drawable.bt_audio_pause_selector);
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            // Handle clicks for btAudioStartPause
        } else if ( v == btAudioNext ) {
            // Handle clicks for btAudioNext
            position+=1;
            if (position>=medialist.size()){
                position=0;
            }
            try {
            MediaItem item=medialist.get(position);
                tvSigner.setText(item.getArtist());
                tvSong.setText(item.getName());
                mservice.openAudio(position);

            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else if ( v == btLyrc ) {
            // Handle clicks for btLyrc
        }
    }

    private void getPlayMode() {
        try {
            int playMode=mservice.getPlayMode();
            if (playMode==MusicPlayerService.REPEAT_NORMAL){
                playMode=MusicPlayerService.REPEAT_SINGLE;  //切换为单曲循环,并把按钮图片切换

            }else if (playMode==MusicPlayerService.REPEAT_SINGLE){
                playMode=MusicPlayerService.REPEAT_ALL;  //如果为单曲循环,切换为循环播放

            }else if (playMode==MusicPlayerService.REPEAT_ALL){
                playMode=MusicPlayerService.REPEAT_NORMAL; //如果为循环播放,则切换为顺序播放,播放全部后,停止播放

            }else {
                playMode=MusicPlayerService.REPEAT_NORMAL; //如果为循环播放,则切换为顺序播放,播放全部后,停止播放
            }

            mservice.setPlayMode(playMode);
            setPlayMode();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    private void setPlayMode() {
        try {
            int playMode=mservice.getPlayMode();
            if (playMode==MusicPlayerService.REPEAT_NORMAL){
                btAudioMode.setBackgroundResource(R.drawable.bt_audio_mode_normal_selector);
                Toast.makeText(this,"顺序播放",Toast.LENGTH_SHORT).show();

            }else if (playMode==MusicPlayerService.REPEAT_SINGLE){
                btAudioMode.setBackgroundResource(R.drawable.bt_audio_mode_single_selector);
                Toast.makeText(this,"单曲循环",Toast.LENGTH_SHORT).show();

            }else if (playMode==MusicPlayerService.REPEAT_ALL){
                btAudioMode.setBackgroundResource(R.drawable.bt_audio_mode_all_selector);
                Toast.makeText(this,"循环播放",Toast.LENGTH_SHORT).show();

            }


        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void checkPlayMode(){
        try {
            int playMode=mservice.getPlayMode();
            if (playMode==MusicPlayerService.REPEAT_NORMAL){
                btAudioMode.setBackgroundResource(R.drawable.bt_audio_mode_normal_selector);

            }else if (playMode==MusicPlayerService.REPEAT_SINGLE){
                btAudioMode.setBackgroundResource(R.drawable.bt_audio_mode_single_selector);

            }else if (playMode==MusicPlayerService.REPEAT_ALL){
                btAudioMode.setBackgroundResource(R.drawable.bt_audio_mode_all_selector);

            }


        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
    Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case UPDATE_SEEKBAR:
                    //1 得到当前进度
                    try {
                        int currentPosition=mservice.getCurrentPosition();

                        seekbarAudio.setProgress(currentPosition);
                        String time=utils.stringForTime(currentPosition)+"/"+utils.stringForTime((int) mservice.getDuration());
                        tvTime.setText(time);

                        handler.removeMessages(UPDATE_SEEKBAR);

                        /**
                         * 每秒刷新下进度条
                         */
                        handler.sendEmptyMessageDelayed(UPDATE_SEEKBAR,1000);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }

                    break;
            }

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG, "onCreate: 音乐播放activity被创建了");
        System.out.println("音乐播放activity被创建了");
        setContentView(R.layout.activity_audioplayer);


        utils=new Utils();
        /**
         * 初始化音乐界面的图片变化的布局
         */
        initView();

        /**
         * 实例化布局里的各个控件
         */
        findViews();

        //注册广播
        registerBorader();

        /**
         * 根据位置获取音乐
         */

            getData();



        /**
         * 绑定服务并启动服务
         */
        bindAndStartService();

        seekbarAudio.setOnSeekBarChangeListener(new MyOnSeekBarChangeListener());
    }

    class MyOnSeekBarChangeListener implements SeekBar.OnSeekBarChangeListener {


        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

            if (fromUser){
                try {
                    mservice.seekTo(progress);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }


        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    }

    private void bindAndStartService() {
        System.out.println("绑定服务 bindService。。。。。。");
        Intent intent=new Intent(this, MusicPlayerService.class);
        //intent.setAction("com.yuanlp.mobilePlayer");
        Bundle bundle=new Bundle();
        bundle.putSerializable("medialist",medialist);
        intent.putExtras(bundle);
        startService(intent);  //不至于多次实例化服务对象
        //System.out.println("数量是多少"+medialist.size());
        bindService(intent,conn,BIND_AUTO_CREATE);
        System.out.println("绑定后,再启动服务");
        // Bundle bundle=new Bundle();
        startService(intent);  //不至于多次实例化服务对象

//        bundle.putSerializable("medialist",medialist);
//        intent.putExtras(bundle);

    }

    /**
     * 与服务创建连接
     */
    private ServiceConnection conn=new ServiceConnection() {
        /**
         * 当连接成功时,回调方法
         * @param name
         * @param service
         */
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            System.out.println("成功连接。。。");
            mservice=IMusicPlayerService.Stub.asInterface(service);

            if (mservice!=null){
                try {

                    if (!isNotifaction){  //不是 从状态栏里过来的,是从列表过来的,那么重新播放
                        System.out.println("成功连接后,service不为空");
                        mservice.openAudio(position);
                    }else{
                        showViewData();

                    }
//                    MediaItem item=medialist.get(position);
//                    String artist=item.getArtist();
//                    String song=item.getName();
//                    tvSigner.setText(artist);
//                    tvSong.setText(song);

                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 当连接失败时回调方法
         * @param name
         */
        @Override
        public void onServiceDisconnected(ComponentName name) {
            System.out.println("连接失败。。。");
            try {
                if (mservice!=null){
                    mservice.stopAudio();
                    mservice=null;
                }

            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };

    private void getData() {
        System.out.println("获取数据------");
        medialist=new ArrayList<MediaItem>();

        medialist= (ArrayList<MediaItem>) getIntent().getSerializableExtra("mediallist");
        System.out.println("当前的list数量------------------------"+medialist.size());
        //得到intent的数据


        isNotifaction = getIntent().getBooleanExtra("Notifaction",false);
        if (!isNotifaction){
            position = getIntent().getIntExtra("position", 0);
        }
        //currentposition = getIntent().getIntExtra("currentPosition",0);
        System.out.println("传到activity里获取的当前进度isNotifaction是------------"+isNotifaction);
    }

    private void initView() {
        System.out.println("初始化跳动的图片");
        iv_play_icon= (ImageView) findViewById(R.id.iv_play_icon);
        iv_play_icon.setBackgroundResource(R.drawable.animation_list);
        AnimationDrawable rocketAnimation= (AnimationDrawable) iv_play_icon.getBackground();
        rocketAnimation.start();
    }


    /**
     * 广播接收,接受来自service里开始播放后发送的广播
     */
    class MyBroadcast extends BroadcastReceiver{
        @Override
        public void onReceive(Context context, Intent intent) {
            /**
             * 接收到广播后,显示歌曲名、歌曲时间等信息
             */
            showViewData();
            checkPlayMode();
        }
    }

    /**
     * 接收到广播后,显示歌曲名、歌曲时间等信息
     */
    private void showViewData() {
        try {
            tvSigner.setText(mservice.getSinger());
            tvSong.setText(mservice.getSong());

            //设置进度条
            seekbarAudio.setMax((int) mservice.getDuration());
            handler.sendEmptyMessage(UPDATE_SEEKBAR);

        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**
     * 注册广播,接收service发送的广播
     */
    private void registerBorader() {
        System.out.println("注册广播");
        broadcast=new MyBroadcast();
        IntentFilter intentfilter=new IntentFilter();
        intentfilter.addAction(MusicPlayerService.OPENAUDIOPLAYER);
        registerReceiver(broadcast,intentfilter);
    }

    /**
     * 在onDestroy里取消注册广播
     */
    @Override
    protected void onDestroy() {
        handler.removeCallbacksAndMessages(null);  //推出activity时,移除所有消息
        if (broadcast!=null){
            unregisterReceiver(broadcast);
            broadcast=null;  //这里为什么把广播设置为null,因为取消注册后,垃圾回收器不一定马上回收广播,如果设置为null,那么会优先回收这个
        }
        super.onDestroy();
    }
}


本文出自 “YuanGuShi” 博客,请务必保留此出处http://cm0425.blog.51cto.com/10819451/1951857

以上是关于手机影音第十五天,利用service实现后台播放音乐,在通知栏显示当前音乐信息等的主要内容,如果未能解决你的问题,请参考以下文章

手机影音第十二天,集成vitamio万能播放器

手机影音第十四天,本地音乐列表的展示与播放(利用视频播放的布局)

手机影音7--视频播放器的基本功能

手机影音第十七天,实现歌词同步

电脑上有啥视频播放器可以用快捷键切换音轨(配音的)

iOS - 无法在后台播放声音