Mediaplayer Cutting Off Sound Too Soon

I've read that the SoundPool class is more suited to short sounds like this than MediaPlayer, but that's probably not the issue.

Can you also post the code for your click handler?

Also, I'd recommend rather than releasing and regaining MediaPlayer instances, use one MediaPlayer instance, and just follow the typical reset(), setDataSource(), prepare(), start() sequence whenever you need to reuse it. It'll be more efficient than constructing a new instance every time. i.e. :

MediaPlayer mp = new MediaPlayer();
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.sound1);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength();
mp.prepare();
mp.start();

//to reuse
mp.reset();
afd = getResources().openRawResourceFd(R.raw.sound2);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength();
mp.prepare();
mp.start();

I had the same problem and it indeed was a garbage collector issue! If you assign the instance of the media player to some local variable inside a method, the instance no longer exists after leaving that method, so GC can randomly delete it anytime.

To avoid this, you need to keep at least one pointer to the instance somewhere else. I have created a static set to keep all the pointers, it looks like this:

private static Set<MediaPlayer> activePlayers = new HashSet<MediaPlayer>();

Then creation of the media player is following:

MediaPlayer player = MediaPlayer.create(context, context.getResources().getIdentifier(id, "raw", pkg));
activePlayers.add(player);
player.setOnCompletionListener(releaseOnFinishListener);
player.start();

Where releaseOnFinishListener is a listener that releases the media player on finish just like yours but also removes the pointer from the activePlayers set:

MediaPlayer.OnCompletionListener releaseOnFinishListener = new MediaPlayer.OnCompletionListener() {
    public void onCompletion(MediaPlayer mp) {
        mp.release();
        activePlayers.remove(mp);
    }
};

I hope this helps you.


well I had the same problems in one project and is because in KindleFire the sounds cut before finish so to fix that (with the release) I added a delay in the release:

    mpNum.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
    {
        public void onCompletion(MediaPlayer mp)
        {
            // Add a handler delay
            new Timer().schedule(new TimerTask() {

                @Override
                public void run() {
                   mp.release();
               }
            }, DELAY_TIME);
        }
    });

It's not the best solution but I think that maybe will help you.