开发者

onCompletion isn't being called when I would expect it to

开发者 https://www.devze.com 2023-02-06 19:47 出处:网络
I have a MediaPlayer member variable posted in my parent class, and after I start it, it doesn\'t ever call onCompletion, or at least onCompletionListener doesn\'t ever catch it? My code looks somethi

I have a MediaPlayer member variable posted in my parent class, and after I start it, it doesn't ever call onCompletion, or at least onCompletionListener doesn't ever catch it? My code looks something to this effect

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

elsewhere in code is my onCompletionListener

mediaPlayer.setOnComplet开发者_高级运维ionListener(new OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {      
        if (repeatFlag == true) {
            handler.removeCallbacks(sampleRunnable);
            handler.postDelayed(sampleRunnable, delay);
        }
    }   
});

I'm using the handler to call sampleRunnable because I want to loop it at a specified delay interval. However, onCompletion seems to never be called. I'm quite positive of this because I've set breakpoints in onCompletion which never suspends the program, and I've tried stepping through and it never seems to be called. Any ideas?


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

This snippet works fine. The only difference is the "@Override" and I'm not sure if the "@Override" has effect on the code.


On my experience, the listener is not triggered on some devices :/


I had this problem as well. It has nothing to do with the Override annotation.

I set the listener before I had configured a Visualizer. I moved the setOnCompletionListener() to after I had accessed the MediaPlayer for the visualizer - this solved my problem. Make sure the method is called at the latest stage.


I had to make a separate class to get it working. No amount of overriding worked.

    private class SoundtrackPlayerListener implements MediaPlayer.OnCompletionListener{

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


I and a couple of other students experienced the same problem in our mobile-apps course.

I'm not sure what the problem is but to us it seems like a bug with the emulator. On some linux machines the OnCompletionEvent didn't fire at all. On ones mac the Event fired in the application but not in the unittests.

Both (application and unittest) worked correctly if executed on a real device instead of the emulator.

The AVD we were using was the Samsung Galaxy Tab (android2.2 api8)


With newer Android versions (from 8 Oreo on) the cause of problem could due to the apps falls asleep. This was the reason that in my app. It fell asleep after playing one song.

You can check and change the the Android battery settings:
1. Battery Optimization
2. tap 'not optimized' then 'all apps'
3. look for your app and change the setting to not optimzed


It was observed while debugging that if you call mediaPlayer.setLooping(true), the onCompletion() method is not called and mediaPlayer starts playing the current track again. This behavior was creating problem in resetting the seekbar's position back to zero in the notification if the user chooses to loop a track. So setting the looping functionality with the help of mediaPlayer created some issues.

Hence a better approach to create a looping functionality is to create a separate variable in the music service class. It will store users choice whether to loop or not, and in the onCompletion() method, you can check this variable and do your operation of either playing the next track or repeating the current track.


Yeah. I confirmed that the issue does happen on some devices. My latest Android phone got this issue but not the old one.

Unless you use streaming audio source, you can replace mMediaPlayer.setOnCompletionListener(...) with

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

It should work :)

0

精彩评论

暂无评论...
验证码 换一张
取 消