当我预期时,onCompletion没有被调用

4

我在父类中有一个MediaPlayer成员变量,启动后它从未调用onCompletion,或者至少onCompletionListener从未捕获它?我的代码大致如下

mediaPlayer = Mediaplayer.create(this, currentSample);
mediaPlayer.start();

在代码的其他地方是我的onCompletionListener。
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {      
        if (repeatFlag == true) {
            handler.removeCallbacks(sampleRunnable);
            handler.postDelayed(sampleRunnable, delay);
        }
    }   
});

我正在使用handler来调用sampleRunnable,因为我想以指定的延迟间隔循环它。但是,onCompletion似乎从未被调用。我非常确定这一点,因为我在onCompletion中设置了断点,但程序从未被挂起,我也尝试过单步执行,但似乎从未被调用。有任何想法吗?
8个回答

6
    mediaPlayer.start();
    mediaPlayer.setOnCompletionListener(new OnCompletionListener() 
    {
        @Override
        public void onCompletion(MediaPlayer arg0) 
        {
            Log.v("Tag", "Completed");
        }
    });

这段代码运行良好。唯一的区别是 "@Override",我不确定 "@Override" 对代码是否有影响。


1
请注意,@Override 只确保您正确地编写了方法签名。如果您的 Java 版本低于 1.6,则它不适用于接口。 - unR
6
为了清晰起见,似乎必须在“start()”之后放置“setOnCompletionListener()”。这对我来说不是很清楚。 - gozzilli
1
@gozzilli 感谢您宝贵的评论,节省了我数小时的努力。 - parul
1
@gozzilli,我认为你应该发表一个答案,这样我们就可以投票支持你了。'Override'显然没有改变任何东西,你的答案是正确的。 - ArnaudR

4
根据我的经验,某些设备上无法触发监听器 :/

1
我注意到这在亚马逊的Kindle Fire、Fire TV和Phone上是正确的。 - user755921

1
我也遇到了这个问题。它与Override注释无关。
在配置可视化器之前,我设置了监听器。我将setOnCompletionListener()移到访问MediaPlayer进行可视化的后面 - 这解决了我的问题。确保该方法在最后阶段被调用。

未解决我的问题,OnCompletion 只被调用了一次。 - Redas Shuliakas

0
我不得不创建一个单独的类来使它工作。无论如何覆盖都没有起作用。
    private class SoundtrackPlayerListener implements MediaPlayer.OnCompletionListener{

    public void onCompletion(MediaPlayer mp) {
                 //completion code here
            }
     }

0

在更新的 Android 版本(从 8 Oreo 开始)中,问题的原因可能是应用程序休眠。这就是我的应用程序出现问题的原因。播放一首歌后,它就会休眠。

您可以检查和更改 Android 电池设置:
1. 电池优化
2. 点击“未优化”,然后点击“所有应用程序”
3. 查找您的应用程序并将设置更改为未优化


这并不是事实,至少在大多数情况下不是。 - Redas Shuliakas

0
在调试过程中观察到,如果调用 mediaPlayer.setLooping(true),则不会调用 onCompletion() 方法,并且 mediaPlayer 会重新播放当前的音轨。这种行为导致在通知中将 seekbar 的位置重置为零时出现问题,如果用户选择循环播放一首音轨。因此,使用 mediaPlayer 设置循环功能会引发一些问题。
因此,更好的方法是在音乐服务类中创建一个单独的变量来实现循环功能。它将存储用户的选择,即是否循环播放,然后在 onCompletion() 方法中,您可以检查该变量并执行相应的操作,如播放下一首音轨或重复当前音轨。

0

我和其他几个学生在移动应用课程中遇到了相同的问题。

我不确定问题是什么,但对我们来说,这似乎是模拟器中的错误。 在一些Linux机器上,OnCompletionEvent根本没有触发。在某些Mac上,事件在应用程序中触发,但在单元测试中未触发。

如果在实际设备上而不是模拟器上执行,则两者(应用程序和单元测试)均可以正常工作。

我们使用的AVD是三星Galaxy Tab(android2.2 api8)。


-1

是的。我确认了这个问题确实会在一些设备上出现。我的最新的安卓手机有这个问题,但旧手机没有。

除非你使用流式音频源,否则你可以用以下代码替换 mMediaPlayer.setOnCompletionListener(...)

new Timer().schedule(new TimerTask() {
  @Override
    public void run() {
      actionWhenAudioEndIsReached();
    }
  }, mMediaPlayer.getDuration());

应该可以工作 :)


2
如果我在文件的中途暂停媒体播放器,然后重新启动,这仍然有效吗? ;) - ocramot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接