【问题标题】:State change listener for MediaPlayerMediaPlayer 的状态变化监听器
【发布时间】:2012-10-27 16:07:22
【问题描述】:

在这张图中有很多states

但使用标准监听器,我只能听到一些基本状态。

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

【问题讨论】:

    标签: android android-mediaplayer


    【解决方案1】:

    不幸的是,我发现除了用自定义状态机容器包围 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) 
        {
        }
    
    }
    

    }

    【讨论】:

    • 我在帖子中添加了一个示例。仅供参考,即使 MP 状态是公开的,我仍然会用这样的容器围绕 MP 来抽象和限制对 MP 的访问。
    • 干得好。工作顺利
    猜你喜欢
    • 2021-02-17
    • 2019-08-10
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多