Home > Enterprise >  Sound starts over and over again
Sound starts over and over again

Time:11-03

I have a property that is set like this:

private MediaPlayer _standBy = null;

Now I would like to use that property in my function playSound().

private void playSound() {
        if (_standBy == null || !_standBy.isPlaying()) {
            _standBy = MediaPlayer.create(_context, R.raw.turbine);
            _standBy.start();
        }
}

That function will be executed whenever I click on a button and the sound should be played only once, no matter how many times I click on that button. Well, that works fine. But since I am repeating that code over and over again but with different properties, I would like to paste that code into another function. That's how I tried it:

private void customizeSound(MediaPlayer mediaplayer) {
        if (mediaplayer== null || !mediaplayer.isPlaying()) {
            mediaplayer= MediaPlayer.create(_context, R.raw.turbine);
            mediaplayer.start();
        }
}

So now playSound() looks like this:

private void playSound() {
        customizeSound(_standBy);
}

And now when I click on that button, the function customizeSound(_standBy) will be executed but the same sound will be started every time when I click on that button.

What's wrong with my code?

CodePudding user response:

Perhaps, you should not always create MediaPlayer instance, should create it only when it is null.

if (mediaplayer == null) {
    mediaplayer = MediaPlayer.create(_context, R.raw.turbine);
}
mediaplayer.start();

And when it is not null, you may switch behavior by isPlaying:

if (mediaplayer.isPlaying()) {
    mediaplayer.seekTo(0);
}
mediaplayer.start();

So these two in one may be like:

if (mediaplayer == null) {
    mediaplayer = MediaPlayer.create(_context, R.raw.turbine);
} else if (mediaplayer.isPlaying()) {
    mediaplayer.seekTo(0);
}
mediaPlayer.start();

Your playSound() method uses a field variable (scope is class wide) while customizeSound method uses local variable (scope is limited in the method block). That is why the latter creates multiple instances.

CodePudding user response:

Try to change the condition to only if the medaplayer is null:

private void customizeSound(MediaPlayer mediaplayer) {
        if (mediaplayer== null) {
            mediaplayer= MediaPlayer.create(_context, R.raw.turbine);
            mediaplayer.start();
        }
}

But this requires to set it to null when it is over:

mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mp) {
        mediaplayer = null;
    }
});
  • Related