Reputation: 11497
I've been trying to achieve a double beep sound on an app I'm developing once a button is pressed.
Problem is, I didn't manage to get it quite right. Sometimes the sounds overlapped, other times they played faster than they should.
I wanted to play an arbitrary tone, have an arbitrary pause/delay and then play the tone again.
OBS: I've seen some solutions for this problem using the MediaPlayer
or the Ringtone
class, but this question is on how to achieve this using ToneGenerator
only, without using the TONE_PROP_BEEP2
or TONE_PROP_ACK
tones.
First of all, I tried to call the startTone()
method twice, but soon I found out that the sounds played simultaneously.
button.setOnClickListener {
val toneG = ToneGenerator(AudioManager.STREAM_ALARM, 100)
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
}
Then I tried to use Handler
in two ways.
First I tried to use two of them:
button.setOnClickListener {
val toneG = ToneGenerator(AudioManager.STREAM_ALARM, 100)
val handler = Handler()
handler.postDelayed({
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
}, 50)
handler.postDelayed({
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
}, 350)
}
Second, I also tried with Thread.sleep()
:
button.setOnClickListener {
val toneG = ToneGenerator(AudioManager.STREAM_ALARM, 100)
val handler = Handler()
handler.postDelayed({
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
Thread.sleep(100)
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
}, 50)
}
Both ideas "kinda" worked. But on the first button press, the beeps sounded funny, as they played way too fast, and sometimes even overlapping.
The second time I pressed the Button
, the tones played correctly.
Upvotes: 0
Views: 3217
Reputation: 735
val toneGen1 = ToneGenerator(AudioManager.STREAM_MUSIC, 100)
toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP, 150)
Handler().postDelayed({
val toneGen1 = ToneGenerator(AudioManager.STREAM_MUSIC, 100)
toneGen1.startTone(ToneGenerator.TONE_CDMA_PIP, 150)
}, 150)
Upvotes: 0
Reputation: 434
this is working for me:
val tg = ToneGenerator(AudioManager.STREAM_ALARM, 1000)
tg.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 2000)
Upvotes: 0
Reputation: 16758
You could try a CountDownTimer and see if it works better.
I actually tried your first option and did not notice the affect you mentioned. I am not sure postDelayed makes any promises other than "Causes the Runnable r to be added to the message queue, to be run after the specified amount of time elapses" , you could also try postAtTime()
instead of postDelayed()
button.setOnClickListener {
val toneG = ToneGenerator(AudioManager.STREAM_ALARM, 100)
val timer = object: CountDownTimer(350,50) {
var skipThisInterval = false
override fun onFinish() {
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
}
override fun onTick(p0: Long) {
if (skipThisInterval) return
skipThisInterval = true
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
}
}
timer.start()
}
using postAtTime()
rather than postDelayed()
might work better also.
button.setOnClickListener {
val toneG = ToneGenerator(AudioManager.STREAM_ALARM, 100)
val handler = Handler()
val timeNow = SystemClock.uptimeMillis()
handler.postAtTime({
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
}, 50 + timeNow)
handler.postAtTime({
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, 200)
}, 350 + timeNow)
}
Upvotes: 0