fix: play through the alarm stream so the ring cuts through DND
DND silences the media stream by default, so playback on STREAM_MUSIC was invisible during DND even though the notification showed. Switch to STREAM_ALARM + USAGE_ALARM, which DND exempts by default, and restore/force the alarm stream volume instead of media.
This commit is contained in:
parent
63791b9f5e
commit
5e5d53ab9b
2 changed files with 20 additions and 16 deletions
13
README.md
13
README.md
|
|
@ -49,11 +49,14 @@ refuse to play any sound.** This is enforced at two points:
|
|||
Only after the user flips that toggle will a trigger actually ring.
|
||||
|
||||
When access **is** granted, `RingService`:
|
||||
- saves the current music volume,
|
||||
- forces `AudioManager.STREAM_MUSIC` to max,
|
||||
- requests `AUDIOFOCUS_GAIN_TRANSIENT` using `USAGE_NOTIFICATION_RINGTONE` and
|
||||
sets `AudioManager.mode = MODE_RINGTONE` so the sound cuts through DND,
|
||||
- plays for 30 s, then restores the volume and abandons focus.
|
||||
- saves the current **alarm-stream** volume,
|
||||
- forces `AudioManager.STREAM_ALARM` to max,
|
||||
- requests `AUDIOFOCUS_GAIN_TRANSIENT` using `AudioAttributes.USAGE_ALARM`,
|
||||
- plays on the **alarm stream** — the one stream Do Not Disturb does **not**
|
||||
silence by default (media/music *is* silenced), which is what lets the ring
|
||||
cut through DND,
|
||||
- plays for the configured number of seconds, then restores the volume and
|
||||
abandons focus.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -147,19 +147,20 @@ class RingService : Service() {
|
|||
*/
|
||||
private suspend fun beginPlayback(uri: Uri): Boolean {
|
||||
return try {
|
||||
// Step 1: save current volume.
|
||||
originalVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
|
||||
// Step 1: save current alarm-stream volume so we can restore it later.
|
||||
originalVolume = audioManager.getStreamVolume(AudioManager.STREAM_ALARM)
|
||||
|
||||
// Step 2: force max volume.
|
||||
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
|
||||
// Step 2: force the alarm stream to max volume.
|
||||
val maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM)
|
||||
audioManager.setStreamVolume(
|
||||
AudioManager.STREAM_MUSIC,
|
||||
AudioManager.STREAM_ALARM,
|
||||
maxVolume,
|
||||
0 // flags = 0 so we do NOT show the system volume UI.
|
||||
)
|
||||
|
||||
// Step 3: request focus. Use USAGE_NOTIFICATION_RINGTONE so the
|
||||
// system lets it play even during DND, and set MODE_RINGTONE.
|
||||
// Step 3: request focus. Playing on the ALARM stream with
|
||||
// USAGE_ALARM is what cuts through Do Not Disturb — DND does not
|
||||
// silence alarms by default (unlike media/music).
|
||||
previousFocusMode = audioManager.mode
|
||||
requestAudioFocus()
|
||||
|
||||
|
|
@ -168,7 +169,7 @@ class RingService : Service() {
|
|||
mediaPlayer = MediaPlayer()
|
||||
mediaPlayer.setAudioAttributes(
|
||||
AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||
.setUsage(AudioAttributes.USAGE_ALARM)
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.build()
|
||||
)
|
||||
|
|
@ -215,7 +216,7 @@ class RingService : Service() {
|
|||
}
|
||||
|
||||
val attributes = AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||
.setUsage(AudioAttributes.USAGE_ALARM)
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.build()
|
||||
|
||||
|
|
@ -230,7 +231,7 @@ class RingService : Service() {
|
|||
@Suppress("DEPRECATION")
|
||||
audioManager.requestAudioFocus(
|
||||
listener,
|
||||
AudioManager.STREAM_MUSIC,
|
||||
AudioManager.STREAM_ALARM,
|
||||
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT
|
||||
)
|
||||
}
|
||||
|
|
@ -276,7 +277,7 @@ class RingService : Service() {
|
|||
// Restore the previous volume.
|
||||
if (originalVolume >= 0) {
|
||||
audioManager.setStreamVolume(
|
||||
AudioManager.STREAM_MUSIC,
|
||||
AudioManager.STREAM_ALARM,
|
||||
originalVolume,
|
||||
0
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue