控制音乐播放器服务片段中的播放暂停按钮

control play pause button in fragment from musicplayer service

我在 android 中创建了一个音乐播放器服务 class 并在一个片段中有一个播放暂停按钮。 我是 运行 音乐播放器服务中的广播流。 该服务在后台 运行。 当应用程序打开服务时,可以通过播放暂停按钮进行控制。 但是当应用程序在后台时,如果我关闭服务播放暂停按钮有时不会改变。我该如何解决

public class RadioStreamFragment extends Fragment {
    //Constant
    private static final String TAG = "RadioStreamFragment";

    //Member variables
    private String mTitle = "";
    private Bitmap mBitmap;
    private boolean mIsPlaying = false;
    private int mMaxVolume;
    private int mVolume;
    private OnSeekBarChangeListener mListener;
    private AudioManager mAudioManager;

    //View member variables
    private TextView mTVTitle;
    //private ImageView mImageView;
    public static  Button mButton;
    private SeekBar mSeekBar;
    private AutoScrollViewPager pager;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAudioManager = (AudioManager) getActivity()
                .getSystemService(Context.AUDIO_SERVICE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_radio, null);

        //Init view
        initView(view);

        return view;
    }

    @Override
    public void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        if (mTitle != null)
            setTitleText(mTitle);
        if (mBitmap != null)
            setImageCover(mBitmap);

        //TODO
        //Create seekBar state
        MainActivity activity = (MainActivity) getActivity();
        mMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

        mSeekBar.setMax(mMaxVolume);
        mSeekBar.setProgress(mVolume);
        if (mListener != null)
            mSeekBar.setOnSeekBarChangeListener(mListener);
        else {
            mSeekBar.setOnSeekBarChangeListener(activity.mSeekBarListener);
        }
        Log.d(TAG, "Volume : " + mVolume + "/" + mMaxVolume);

        //Button state
        setButtonState(mIsPlaying);

        Log.d(TAG, "Resumed");
    }

    /* Property access functions
     * 
     */
    public void setTitleText(String title) {
        mTitle = MainActivity.Songtitle;
        mTVTitle.setText(MainActivity.Songtitle);
    }
    public void setImageCover(Bitmap bitmap) {
        mBitmap = bitmap;
    //  mImageView.setImageBitmap(bitmap);
    }
    public void setButtonState(boolean isPlaying) {
        mIsPlaying = isPlaying;
        final int sdk = android.os.Build.VERSION.SDK_INT;
        if (isPlaying) {
            if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                mButton.setBackgroundDrawable(getResources()
                        .getDrawable(R.drawable.btn_pause_radio));
            } else {
                mButton.setBackground(getResources()
                        .getDrawable(R.drawable.btn_pause_radio));
            }
        } else {
            if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                mButton.setBackgroundDrawable(getResources()
                        .getDrawable(R.drawable.btn_play_radio));
            } else {
                mButton.setBackground(getResources()
                        .getDrawable(R.drawable.btn_play_radio));
            }
        }
    }
    public void setMaxVolume(int value) {
        mMaxVolume = value;
    }
    public void setVolume(int value) {
        mVolume = value;
    }
    public void setOnSeekBarChangeListener(OnSeekBarChangeListener listener) {
        mListener = listener;
    }
    public int getMaxVolume() {
        return mMaxVolume;
    }
    public int getVolume() {
        return mVolume;
    }
    public SeekBar getVolumeSeekBar() {
        return mSeekBar;
    }
    public String getTitleText() {
        return mTitle;
    }

    /* Internal Functions
     * 
     */
    Button hbir;
    Button lb;
    private Handler handler;
    private void initView(View view) {
        final int sdk = android.os.Build.VERSION.SDK_INT;
        mTVTitle = (TextView) view.findViewById(R.id.tv_title);
    //  mImageView = (ImageView) view.findViewById(R.id.im_radio_image);
        mButton = (Button) view.findViewById(R.id.btn_play);    
        mButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                MainActivity.tryagain=false;
                doPlay(v);
            }
        });

        hbir = (Button) view.findViewById(R.id.hbit);   
        hbir.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                hbir.setEnabled(false);
                lb.setEnabled(false);
                mButton.setEnabled(false);
                Data.Initialize();

                Data.Initializehbit();
                MainActivity.tryagain=false;
                try{MainActivity.stopRadio();

                MainActivity.playRadio();
                if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    mButton.setBackgroundDrawable(getResources()
                            .getDrawable(R.drawable.btn_pause_radio));
                } else {
                    mButton.setBackground(getResources()
                            .getDrawable(R.drawable.btn_pause_radio));
                }
                as=false;

                }
                catch(Exception e){}

                hbir.setEnabled(false);
                lb.setEnabled(true);
                mButton.setEnabled(true);
            }
        });

        lb = (Button) view.findViewById(R.id.lbit); 
        lb.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                hbir.setEnabled(false);
                lb.setEnabled(false);
                mButton.setEnabled(false);
                Data.Initialize();
                final int sdk = android.os.Build.VERSION.SDK_INT;
                MainActivity.tryagain=false;

                try{MainActivity.stopRadio();
                MainActivity.playRadio();
                if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    mButton.setBackgroundDrawable(getResources()
                            .getDrawable(R.drawable.btn_pause_radio));
                } else {
                    mButton.setBackground(getResources()
                            .getDrawable(R.drawable.btn_pause_radio));
                }
                as=false;
                }
                catch(Exception e){}

                hbir.setEnabled(true);
                lb.setEnabled(false);
                mButton.setEnabled(true);
            }
        });
        mSeekBar = (SeekBar) view.findViewById(R.id.sb_volume);
        mTVTitle.setText(MainActivity.Songtitle);


    /*  String[] imageUrls = new String[Imageurl.newyearsvalues.size()];
        for(int i=0; i<Imageurl.newyearsvalues.size(); i++)
        {
            ModelWPCategory modelWPCategory = new ModelWPCategory();
            modelWPCategory = wpCategories.get(i);
        //  categoryNames[i]= Imageurl.newyearsvalues.get(i);
            Log.d("kd", ""+Imageurl.newyearsvalues.get(i));
            imageUrls[i] = Imageurl.newyearsvalues.get(i);;
        }
        //int pagerPosition = bundle.getInt(Extra.IMAGE_POSITION, 0);

        ImagePagerAdapter im = new ImagePagerAdapter(imageUrls);
        pager = (AutoScrollViewPager) view.findViewById(R.id.pagera);
        pager.setAdapter(im);
        pager.setCurrentItem(0);
        pager.startAutoScroll();

        pager.setScrollbarFadingEnabled(true);
        Animation anim = AnimationUtils.loadAnimation(MainActivity.c, R.anim.fade_out);
        anim.setRepeatMode(Animation.REVERSE);

        pager.startAnimation(anim);
        anim.start();*/
        /*   handler = new Handler();
           handler.postDelayed(new Runnable() {
                public void run() {
                    int i = pager.getCurrentItem();
                    if(i>=(pager.getAdapter().getCount()-1))
                        i=0;
                    else
                        i++;
                    pager.setCurrentItem(i);
                    pager.getAdapter().notifyDataSetChanged();
                }
            },5000);*/

    //  mTVTitle.setText("Radio Station");

    }
    public static boolean as=false;
    public void doPlay(View view) {
        final int sdk = android.os.Build.VERSION.SDK_INT;
        if (!mIsPlaying && view.getId() == R.id.btn_play) {
            MainActivity.playRadio();
            if(as){
            try{
            if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                view.setBackgroundDrawable(getResources()
                        .getDrawable(R.drawable.btn_play_radio));
            } else {
                view.setBackground(getResources()
                        .getDrawable(R.drawable.btn_play_radio));
            }
            }catch(Exception e)
            {}
            as=false;
            }
            else
            {as=true;
            try{
                if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    view.setBackgroundDrawable(getResources()
                                .getDrawable(R.drawable.btn_pause_radio));
                    } else {
                        view.setBackground(getResources()
                                .getDrawable(R.drawable.btn_pause_radio));
                    }
                }catch(Exception e)
                {}
            }
        } else  {
            MainActivity.stopRadio();
            if(as){
                try{
                if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                    view.setBackgroundDrawable(getResources()
                            .getDrawable(R.drawable.btn_play_radio));
                } else {
                    view.setBackground(getResources()
                            .getDrawable(R.drawable.btn_play_radio));
                }
                }catch(Exception e)
                {}
                as=false;
                }
                else
                {as=true;
                try{
                    if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
                        view.setBackgroundDrawable(getResources()
                                    .getDrawable(R.drawable.btn_pause_radio));
                        } else {
                            view.setBackground(getResources()
                                    .getDrawable(R.drawable.btn_pause_radio));
                        }
                    }catch(Exception e)
                    {}
                }
        }


    }

}

音乐播放器服务class

import java.io.IOException;


import com.spoledge.aacdecoder.MultiPlayer;
import com.spoledge.aacdecoder.PlayerCallback;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class MusicPlayerService extends Service {
    //Constant
    public static final String NOTIFICATION = "com.vg.intent.notification.musicplayer";
    public static final String STATUS = "STATUS";
    public static final String STATUS_PLAYING = "Playing";
    public static final String STATUS_STOPPED = "Stopped";
    public static final String STATUS_BUFFERING = "Buffering";
    public static final String STATUS_SERVICE_STARTED = "ServiceStarted";

    public static final String PLAY_THIS_ONE = "PlayThisOne";

    //Member variables
    private static final String TAG = "MusicPlayerSevices";
    private StreamBinder mBinder;
    private MediaPlayer mMediaPlayer;
    private MultiPlayer mPlayer;
    private PlayerCallback mPlayerCallback;
    private Handler mHandler;
    private boolean mIsMP3Pause = false;

    //Radio state variables
    private String mRadioTitle;
    private boolean mIsPlaying = false;

    /* Service Lifecycle Event Handler
     * (non-Javadoc)
     * @see android.app.Service#onCreate()
     */
    @Override
    public void onCreate() {
        mBinder = new StreamBinder();
        initMusicPlayer();
        super.onCreate();
        sendNotification(STATUS, STATUS_SERVICE_STARTED);
        mHandler = new Handler();
        Log.d(TAG, "onCreate complete");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (mBinder == null)
            mBinder = new StreamBinder();
        if (mPlayer == null)
            initMusicPlayer();
        if (mMediaPlayer == null)
            mMediaPlayer = new MediaPlayer();

        handlingRequest(intent);
        Log.d(TAG, "onStartCommand complete");
        return Service.START_NOT_STICKY; //START_NOT_STICKY still work
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
    /* MusicPlayerSevice functions
     * 
     */
    public void playRadio(final String url) {
        if (mIsMP3Pause) {
            mMediaPlayer.start();
            mIsMP3Pause = false;
        } else {
            //TODO
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
                    final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
                    // Connectivity issue, we quit
                    if (networkInfo == null || networkInfo.getState() != NetworkInfo.State.CONNECTED) {
                        return;
                    }

                    String newUrl = "";
                    if (url.contains(".m3u")) {
                        newUrl = ParserM3UToURL.parse(url);
                    } else {
                        newUrl = url;
                    }
                    final String finalUrl = newUrl;
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            mIsPlaying = true;
                            if (finalUrl.endsWith(".mp3")) {
                                //TODO
                                //Create media player to play instead
                                Log.d(TAG, "Start media player");
                                mPlayer.stop();
                                try {
                                    mMediaPlayer.setDataSource(finalUrl);
                                    mMediaPlayer.prepareAsync();
                                } catch (IllegalArgumentException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                } catch (SecurityException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                } catch (IllegalStateException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                } catch (IOException e) {
                                    // TODO Auto-generated catch block
                                    e.printStackTrace();
                                }
                                mMediaPlayer.start();
                                mIsMP3Pause = false;
                            } else {
                                Log.d(TAG, "Start multi player");
                                mPlayer.playAsync(finalUrl);
                            }
                        }
                    });
                }
            });
            thread.start();
        }
    }
    public void stopRadio() {
        mIsPlaying = false;
        if (mMediaPlayer.isPlaying()) {
            Log.d(TAG, "Stop media player");
            mMediaPlayer.stop();
        } else {
            Log.d(TAG, "Stop multi player");
            mPlayer.stop();
        }
    }
    public void pauseRadio() {
        mIsPlaying = false;
        if (mMediaPlayer.isPlaying()) {
            Log.d(TAG, "Pause media player");
            mIsMP3Pause = true;
            mMediaPlayer.pause();
        } else {
            Log.d(TAG, "Stop multi player");
            mPlayer.stop();
        }
    }
    public String getRadioTitle() {
        return mRadioTitle;
    }
    public boolean isPlaying() {
        return mIsPlaying;
    }

    //Internal function
    private void initMusicPlayer() {
        if (mPlayer == null) {
            mPlayerCallback = new PlayerCallback() {    



                @Override
                public void playerStopped(int perf) {
                    sendNotification(STATUS, STATUS_STOPPED);
                }

                @Override
                public void playerStarted() {
                    sendNotification(STATUS, STATUS_PLAYING);
                }

                @Override
                public void playerPCMFeedBuffer(boolean isPlaying, int bufSizeMs, int bufCapacityMs) {
                    if (!isPlaying) {
                        sendNotification(STATUS, STATUS_BUFFERING);
                    }
                }

                @Override
                public void playerMetadata(String key, String value) {
                    if (key != null && key.equals("StreamTitle")) {
                        mRadioTitle = Utils.stripHtml(value);
                        sendNotification(STATUS, mRadioTitle);
                    }
                }

                @Override
                public void playerException(Throwable throwable) {
                    final Throwable finalThrow = throwable;
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            stopRadio();
                            Toast.makeText(getApplicationContext(), finalThrow.getMessage()
                                    , Toast.LENGTH_LONG).show();
                            sendNotification(STATUS, STATUS_STOPPED);
                        }
                    });
                }           
                @Override
                public void playerAudioTrackCreated(AudioTrack arg0) {}
            };
            //Workaround
            try {
                java.net.URL.setURLStreamHandlerFactory( new java.net.URLStreamHandlerFactory(){
                    public java.net.URLStreamHandler createURLStreamHandler( String protocol ) {
                        Log.d( TAG, "Asking for stream handler for protocol: '" + protocol + "'" );
                        if ("icy".equals( protocol )) return new com.spoledge.aacdecoder.IcyURLStreamHandler();
                        return null;
                    }
                });
            }
            catch (Throwable t) {
                Log.w( TAG, "Cannot set the ICY URLStreamHandler - maybe already set ? - " + t );
            }
            mPlayer = new MultiPlayer(mPlayerCallback);
        }
    }
    private void handlingRequest(Intent intent) {
        Bundle bundle = intent.getExtras();
        if (bundle != null) {
            String url = bundle.getString(PLAY_THIS_ONE);
            if (url != null) {
                playRadio(url);
                Log.d(TAG, "Receive playing request : " + url);
            }
            else {
                stopRadio();
                Log.d(TAG, "Receive stop request");
            }
        }
    }
    private void sendNotification(String key, String value) {
        Intent intent = new Intent(NOTIFICATION);
        intent.putExtra(key, value);
        sendBroadcast(intent);
    }

    // Nested class
    public class StreamBinder extends Binder {
        public MusicPlayerService getService() {
            return MusicPlayerService.this;
        }
    }

}

从片段/activity到服务的通信就像将数据从activity传递到activity。

将您的数据(可能是一个 int,表示暂停您的应用程序)放入一个 intent 并使用该 intent 启动服务。 onStartCommand 将触发,您的服务从意图中提取数据 int 意识到这是一个暂停命令并暂停。

从服务到应用程序的通信很棘手。方法太多,无法在一个答案中涵盖。

您必须将播放器服务视为一个自动机。在任何时候,它都可能处于任何状态 X,例如 state.Playing , state.Pause ...每当您在用户返回应用程序时重新创建视图(通过片段或 activity ) 你必须请求媒体播放器给你当前状态并根据它绘制你的界面按钮。因此,每次重新创建片段或 activity 时,都会向您的服务发送一个意图,询问其状态。该服务应调用类似 getState() 的方法。然后,从服务和意图中广播其状态,例如 state.STOP。在你的 fragment/activity 中,必须有一个 BroadcastReceiver 注册了这个意图的听证会,这样,当收到状态意图时,你相应地更新你的按钮,就是这样:)