Cannot get android MediaPlayer onCompletion to fire

Actually, the reason is that the MediaPlayer is a local variable. After the function finished, the MediaPlayer is collected by GC. So the fix is easy, make your MediaPlayer a member of the class.

YourClassName {
    MediaPlayer mp = new MediaPlayer(); 

    void YourFunction() {
          mp.setDataSource(context, Uri.parse(soundUrl)); 
          mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 
          mp.setLooping(false); 
          mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
              @Override 
              public void onCompletion(MediaPlayer mp) { 
                  Log.i(LOGTAG, "onComplete hit"); 
                  mp.stop(); 
                  mp.release(); 
              }
          });         
          mp.prepare(); 
          mp.start();
    }
}

I was encountering similar symptoms to this, and the root cause was that the MediaPlayer was getting garbage collected before the OnCompletionListener was being called.

Judging from your code, it looks like the same problem - your code doesn't hold a long-lived reference to the MediaPlayer, so as soon as that function ends (and before the audio finishes playing) the MediaPlayer is susceptible to GC.

This problem is identifiable by this log line:

02-22 13:14:57.969: W/MediaPlayer-JNI(16888): MediaPlayer finalized without being released

You can fix it by rearchitecting the class such that the MediaPlayer reference is kept for longer - by storing a reference to it in the activity, and reusing the same instance to play the same sound multiple times, for example.

There's a more detailed explanation here: Garbage Collection causes : MediaPlayer finalized without being released


Here is how I have it:

    video.setOnCompletionListener(this);
    IntroClip.execute(video);
}

@Override
public void onCompletion(MediaPlayer mp){
    Button LoginButton;
    Button CreateAccount;
    Button RecoverPass;

    setContentView(R.layout.loginmenu);
    Spin = (ProgressBar)findViewById(R.id.Spinner);

    mp.release();       
}

It's actually simple (but silly). Set your listener after you call start(), like so:

ediaPlayer mp = new MediaPlayer(); 
mp.setDataSource(context, Uri.parse(soundUrl)); 
mp.setAudioStreamType(AudioManager.STREAM_MUSIC); 
mp.setLooping(false); 
mp.prepare(); 
mp.start();
mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { 
    @Override 
            public void onCompletion(MediaPlayer mp) { 
                Log.i(LOGTAG, "onComplete hit"); 
                mp.stop(); 
                mp.release(); 
            } 
    });