I published an app recently, and users are reporting crashes because my program included the method setNextMediaPlayer()
. I now realize that this only works for API 16+, and my app supports API 8+. I was wondering if there is an alternate way of achieving the same effect.
My app has some text to speech, and what I was doing was creating an ArrayList
of MediaPlayers
that each had a short sound file, and then playing them one after an other. If I remove this method from the code, the audio becomes too choppy to understand.
I was thinking about using the SoundPool
class, but there is no OnCompleteListener
, so I'm not sure how I would do it.
So basically my question is: Is there a way to transition seamlessly between audio files without using the setNextMediaPlayer()
method?
Thanks very much for your time!
EDIT
I added this code that I found
private class CompatMediaPlayer extends MediaPlayer implements OnCompletionListener {
private boolean mCompatMode = true;
private MediaPlayer mNextPlayer;
private OnCompletionListener mCompletion;
public CompatMediaPlayer() {
try {
MediaPlayer.class.getMethod("setNextMediaPlayer", MediaPlayer.class);
mCompatMode = false;
} catch (NoSuchMethodException e) {
mCompatMode = true;
super.setOnCompletionListener(this);
}
}
public void setNextMediaPlayer(MediaPlayer next) {
if (mCompatMode) {
mNextPlayer = next;
} else {
super.setNextMediaPlayer(next);
}
}
@Override
public void setOnCompletionListener(OnCompletionListener listener) {
if (mCompatMode) {
mCompletion = listener;
} else {
super.setOnCompletionListener(listener);
}
}
@Override
public void onCompletion(MediaPlayer mp) {
if (mNextPlayer != null) {
// as it turns out, starting a new MediaPlayer on the completion
// of a previous player ends up slightly overlapping the two
// playbacks, so slightly delaying the start of the next player
// gives a better user experience
SystemClock.sleep(50);
mNextPlayer.start();
}
mCompletion.onCompletion(this);
}
}
But now how do I add the audio files? I tried this:
// assigns a file to each media player
mediaplayers = new ArrayList<CompatMediaPlayer>();
for (int i = 0; i < files.size(); i++) {
mediaplayers.add((CompatMediaPlayer) CompatMediaPlayer.create(this, files.get(i)));
}
but am getting a class cast exception because MediaPlayer cannot be casted to CompatMediaPlayer.
Create Compat player that will work with onCompletionListener
to start the next player like:
public void onCompletion(MediaPlayer mp) {
if (mCompatMode && mNextPlayer != null) {
mNextPlayer.prepare();
mNextPlayer.start();
}
}
Somewhere in your constructor check if there is method (or check SDK version) named "setNextMediaPlayer"
mCompatMode = Build.VERSION.SDK_INT < 16;
Define method like this one:
public void setNextMediaPlayer(MediaPlayer next) {
if (mCompatMode) {
mNextPlayer = next;
} else {
super.setNextMediaPlayer(next);
}
}