状态更改MediaPlayer的侦听器

new*_*rld 10 android android-mediaplayer

在这个图中有很多状态:

MediaPlayer声明

但是对于标准听众,我只能听一些基本的状态.

那么可以听取MediaPlayer的每个状态变化吗?

pai*_*ego 5

不幸的是,除了使用自定义状态机容器包围MediaPlayer之外,我没有办法做到这一点.

添加 ...

您可以创建一个单例容器并定义它​​自己的状态.与MediaPlayer的唯一交互是通过此容器完成的.所有其他类都需要访问容器的API.

以下是一个简单的概述:

public class MyContainer implements OnBufferingUpdateListener, 
                                            OnCompletionListener, 
                                            OnErrorListener,  
                                            OnInfoListener, 
                                            OnPreparedListener 
{
    static enum MP_STATES
    {
        MPS_IDLE,
        MPS_INITIALIZED,
        MPS_PREPARING,
        MPS_PREPARED,
        MPS_STARTED,
        MPS_STOPPED,
        MPS_PAUSED,
        MPS_PLAYBACK_COMPLETED,
        MPS_ERROR,
        MPS_END,
    }

    private static MyContainer s_mpm = null;
    private MP_STATES m_eState;
    private MediaPlayer m_mp;

    public static MyContainer get()
    {
        if (null == s_mpm)
        {
            s_mpm = new MyContainer();          
        }
        return s_mpm;
    }

    private MyContainer()
    {       
        m_mp = new MediaPlayer();
        m_mp.setOnBufferingUpdateListener(this);
        m_mp.setOnCompletionListener(this);
        m_mp.setOnErrorListener(this);
        m_mp.setOnInfoListener(this);
        m_mp.setOnPreparedListener(this);

        m_eState = MP_STATES.MPS_IDLE;
    }

    public MP_STATES getState()
    {
        return m_eState;
    }

    public void setUrl(String szUrl)
    {
        bringToIdleState();

        try {
            m_mp.setDataSource(szUrl);
            m_eState = MP_STATES.MPS_INITIALIZED;
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        m_mp.prepareAsync();
        m_eState = MP_STATES.MPS_PREPARING;
    }

    public void play()
    {
        switch (m_eState)
        {
            case MPS_PREPARED:
            case MPS_PAUSED:
                m_mp.start();
                m_eState = MP_STATES.MPS_STARTED;
                break;
            default:
                // !! throw exception
        }       
    }

    public void pause()
    {
        switch (m_eState)
        {
            case MPS_STARTED:
                m_mp.pause();
                m_eState = MP_STATES.MPS_PAUSED;
                break;
            default:
                // !! throw exception
        }       
    }

    public void release() 
    {
        m_mp.release();
        m_mp = null;
    }

    private void bringToIdleState()
    {
        // reset() should bring MP to IDLE
        m_mp.reset();
        m_eState = MP_STATES.MPS_IDLE;      
    }   

    // ** Callbacks

    @Override
    public void onPrepared(MediaPlayer mp) 
    {
        m_eState = MP_STATES.MPS_PREPARED;    
        m_mp.start();
        m_eState = MP_STATES.MPS_STARTED;           
    }

    @Override
    public boolean onInfo(MediaPlayer mp, int what, int extra) 
    {
        return false;
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) 
    {
        m_eState = MP_STATES.MPS_IDLE;
        return false;
    }

    @Override
    public void onCompletion(MediaPlayer mp) 
    {
          // play the next song
    }

    @Override
    public void onBufferingUpdate(MediaPlayer mp, int percent) 
    {
    }

}
Run Code Online (Sandbox Code Playgroud)

}

  • 我在帖子中添加了一个例子.fyi,即使MP状态是公开的,我仍然会用这样一个容器包围MP,只是为了抽象并限制对MP的访问. (2认同)