Android - problém s přehráváním krátkého zvuku v aplikaci (MediaPlayer, SoundPool, RingtoneManager, ToneGenerator)
Při vývoji Android aplikace v Javě jsem měl jednoduchou globální funkci pro zobrazování zpráv ve SnackBaru. V případě chyby se měl přehrát úplně základní krátký zvuk – a právě tahle drobnost se ukázala jako nečekaný zdroj problémů, kdy aplikace nahodile zamrzala.
Najít příčinu bylo navíc komplikované, protože se v Logcatu neobjevovala žádná chyba, která by na problém ukazovala.
Nejprve jsem zkusil přehrávat zvuk přes MediaPlayer, ale aplikace občas spadla – a jindy zase zvuk bez problémů přehrála.
Problém nevyřešilo ani odchytávání vyjímek.
MediaPlayer mp = MediaPlayer.create(activity, R.raw.error);
mp.start();
Následoval pokus se SoundPool a chování bylo podobné jako pro MediaPlayer.
Problém nevyřešilo ani odchytávání vyjímek, ani singleton.
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);
Nakonec se osvědčilo použití systémových notifikací přes RingtoneManager
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) {}
}
Ale dobře funguje i generátor zvuků ToneGenerator. Ovšem při testování na čtečce Zebra se zvuk nepřehrával.
public static void playBeep() {
ToneGenerator toneGen = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
toneGen.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200);
}
Vítězem tedy je RingtoneManager.
Show english version