Android – Issue with Playing Short Sounds in the App (MediaPlayer, SoundPool, RingtoneManager, ToneGenerator)
During the development of an Android application in Java, I had a simple global function for displaying messages in a SnackBar. In case of an error, a very basic short sound was supposed to play – and this tiny detail turned out to be an unexpected source of problems, causing the app to freeze intermittently.
Finding the cause was further complicated because no error appeared in Logcat indicating the problem.
At first, I tried playing the sound via MediaPlayer, but the app sometimes crashed – while at other times it played the sound without issues.
Catching exceptions did not solve the problem either.
MediaPlayer mp = MediaPlayer.create(activity, R.raw.error);
mp.start();
Next, I tried using SoundPool, and the behavior was similar to MediaPlayer.
Neither catching exceptions nor using a singleton solved the problem.
soundPool = new SoundPool.Builder()
.setMaxStreams(1)
.setAudioAttributes(audioAttributes)
.build();
errorSoundId = soundPool.load(context, R.raw.error, 1);soundPool.play(errorSoundId, 1, 1, 1, 0, 1f);
Eventually, using system notifications via RingtoneManager proved reliable.
public static void playSystemNotification(AppCompatActivity activity) {
try {
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
if (uri != null) {
Ringtone r = RingtoneManager.getRingtone(activity, uri);
if (r != null) {
r.play();
}
}
} catch (Exception ignored) {}
}
The ToneGenerator also works well. However, when testing on a Zebra scanner, the sound did not play.
public static void playBeep() {
ToneGenerator toneGen = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
toneGen.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);
}
The winner, therefore, is RingtoneManager.