【问题标题】:Android mediaPlayer - is there an "isPrepared()" or "getStatus()" method?Android mediaPlayer - 是否有“isPrepared()”或“getStatus()”方法?
【发布时间】:2012-08-06 06:06:16
【问题描述】:

我在使用 Android 的 MediaPlayer 时遇到问题。它似乎缺少重要的功能,主要是获取 MediaPlayer 的当前状态或了解它是否准备好的方法。我知道有准备好的监听器,但是 MediaPlayer 的持续时间比 Activity 长,所以当播放 Activity 恢复时,获取当前播放器状态会很好,无论它是否尝试加载媒体,是否加载媒体等. 是我遗漏了什么,还是我必须自己跟踪玩家状态?

其他很好的功能是 onPlayStateChanged() - 我目前必须手动跟踪播放状态。我做错了吗?

【问题讨论】:

    标签: android android-mediaplayer


    【解决方案1】:

    希望现在给出答案还为时不晚。 MediaPlayer 类没有 isPrepared() 或 getStatus() 方法,您必须自己跟踪其状态。不过,这并不难。

    MediaPlayer 类有一个非常有用的状态图。您应该根据该图实现您的服务。此外,如果您总是从同一个线程控制 MediaPlayer 对象,则很容易跟踪其状态,因此我建议您这样做。 prepareAsync() 方法是您必须处理的唯一异步方法,但您可以保留一个布尔值,指示播放器正在准备中,从 prepareAsync() 调用直到 onPrepared() 为“真”叫。无论如何,如果您不小心从非法状态调用任何方法,您始终可以实现 onError 并捕获 IllegalStateException 以避免崩溃。

    不过,media playback guide 给了我很多帮助。

    【讨论】:

    • 将此标记为已接受的答案。可悲的现实是,用于媒体播放/消费的 Android 确实缺乏,甚至缺少状态检索等基本功能。最好的解决方法是您自己编写一个 MediaPlayer 对象的包装器并自己存储状态。
    • 我自己也遇到了这个问题。考虑到其方法对当前状态的敏感程度,这是一个如此荒谬的疏忽。
    • 至少他们可以做“无操作”而不是在状态机中抛出残酷的IllegalStateException
    【解决方案2】:

    我需要在调试时查看状态以解决问题,所以在我知道 MediaPlayer 已经准备好后,我只是将这段代码放在了某处:

    try {
        this.audioPlayer.prepare();
    } catch (Exception e) {
    }
    

    这会向控制台打印一个错误,例如“E/MediaPlayer:在状态 32 中调用 prepareAsync”。

    现在如果我能找到一个列出所有状态代码的地方...

    【讨论】:

    • 如果代码处于错误状态,可能会抛出异常;但它实际上是为了开始一个新的状态而设计的——在大多数情况下,这不是你想要的。
    • 根据 MediaPlayer 文档 (developer.android.com/reference/android/media/…),如果在除 Initialized 状态之外的任何状态下调用 prepare() 都会抛出异常。所以我的建议是在你知道 MediaPlayer 已经准备好之后使用它应该可以可靠地工作。
    【解决方案3】:

    我发现了一些可能对你和其他人有帮助的东西。 MediaPlayer 类中有一个setOnPreparedListener() 函数,可以让您在准备好MediaPlayer 时运行一段代码。

    另外,如果您想确保您的媒体已加载,您可以使用getDuration() 函数。此代码以毫秒为单位返回持续时间,如果没有可用的持续时间,则返回 -1。下面是代码:

    yourMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            if(yourMediaPlayer.getDuration() != -1){
                //your code when when something is loading
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      MediaPlayer 类没有 getState,但在内部它有一个状态,正如 alex.magellan 所解释的那样。在“不允许的状态”处调用方法会导致异常。

      为了避免这些,我创建了一个 StateMachineMediaPlayerWrapper 类。所以不是直接调用MediaPlayer,而是使用MediaPlayerWrapper,它在内部更新StateMachine并暴露getState()方法。

      StateMachineWrapper 类实现可以是found here.

      【讨论】:

        【解决方案5】:

        我认为没有办法通过 MediaPlayer 类本身来做到这一点。

        最简单的做法是在创建和重置时将全局变量设置为 true。它在发布时设置为 false。

        boolean playerAvailable = true;
        
        mediaPlayer = MediaPlayer.create(myContext, soundId); // ready to play
        
        playerAvailable = true;
        
        ....
        
        mediaPlayer.reset();   // ready to play again
        
        playerAvailable = true;
        
        ....
        
        mediaPlayer.release(); // can't be played until release.
        
        playerAvailable = false;
        

        【讨论】:

        • 7年前我问了这个问题真是太疯狂了,Android团队仍然没有解决这个问题。
        【解决方案6】:

        您可以通过使用预定义的布尔变量并在调用 onPrepared() 回调时将其设置为 true 并在 MediaPlayer 启动时将其设置为 false 来解决此问题。例如:

        public boolean mpPrepared = false;
        
        mp.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                mpPrepared = true;
            }
        });
        
        mp.start();
        mpPrepared = false;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多