I am working in a gallery of images that include an audio of how the things that the user is viewing on the screen are pronounced, which is executed with a button also included in the screen.
The following code works, but sometimes the audio is cut before it finishes reproducing, the problem with this is that I am not receiving any error log.
View.OnClickListener eventoPlay = (v) → {
@Override
public void onClick(View v) {
btnPlaySound.setClickable(false);
try{
Uri myUri = Uri.parse(urlroot + urlAudio); //global variables by current image
final MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mediaPlayer.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
btnPlaySound.setClickable(true);
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
btnPlaySound.setClickable(true);
Log.e("Error in media player", String.valueOf(what));
Log.e("Error in media player", String.valueOf(extra));
return false;
}
});
mediaPlayer.prepareAsync();
}catch (Exception e){
e.printStackTrace();
btnPlaySound.setClickable(true);
}
}
};
btnPlaySound.setOnClickListener(eventoPlay);
btnPlaySound.performClick();
These are the scenarios that I have debugged:
-setOnPreparedListener()
call naturally, always (the audio starts playing always).
-setOnCompletionListener()
call only if the audio was finished playing (if the audio was not cut).
-setOnErrorListener()
It never call, regardless of whether the audio is cut.
-catch
This block is never executed either, regardless of whether the audio is cut.
I tested in devices like Samsung tab S3, Samsgung tab E, Samsung tab A, Alcatel A3, Xiaomi MiA2, Swissmobility. In the most powerful devices happens less frequently. but I want this failure never to occur.
Tnks.
You may want to ensure btnPlaySound.setClickable(true) is being called on the UI thread. It could be causing an error. Also the media player may be getting garbage collected before finishing keep a (strong) reference to the MediaPlayer to prevent garbage collection.
Try this to test if it being garbage collected:
View.OnClickListener eventoPlay = (v) → {
@Override
public void onClick(View v) {
btnPlaySound.setClickable(false);
try{
Uri myUri = Uri.parse(urlroot + urlAudio); //global variables by current image
// KEEP A STRONG REFERENCE
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(getApplicationContext(), myUri);
mediaPlayer.setLooping(false);
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mp.start();
}
});
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.release();
btnPlaySound.setClickable(true);
}
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
mp.release();
btnPlaySound.setClickable(true);
Log.e("Error in media player", String.valueOf(what));
Log.e("Error in media player", String.valueOf(extra));
return false;
}
});
mediaPlayer.prepareAsync();
}catch (Exception e){
e.printStackTrace();
btnPlaySound.setClickable(true);
}
}
};
btnPlaySound.setOnClickListener(eventoPlay);
btnPlaySound.performClick();