From c5e5d23dab9d1c1e41d15a7234619be8f0f68d31 Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Wed, 11 Sep 2024 12:01:34 -0500 Subject: [PATCH] fix: handle Android 15+ restriction on audio focus requests Do not attempt to play sounds if audio focus request failed See: https://developer.android.com/about/versions/15/behavior-changes-15#audio-focus "Apps that target Android 15 (API level 35) must be the top app or running a foreground service in order to request audio focus. If an app attempts to request focus when it does not meet one of these requirements, the call returns AUDIOFOCUS_REQUEST_FAILED" --- .../ichi2/anki/cardviewer/SoundTagPlayer.kt | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/SoundTagPlayer.kt b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/SoundTagPlayer.kt index c363305a5008..f722545dadf0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/SoundTagPlayer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/SoundTagPlayer.kt @@ -21,6 +21,7 @@ import android.media.AudioAttributes import android.media.AudioManager import android.media.MediaPlayer import android.net.Uri +import androidx.annotation.CheckResult import androidx.annotation.VisibleForTesting import androidx.media.AudioFocusRequestCompat import androidx.media.AudioManagerCompat @@ -130,10 +131,14 @@ class SoundTagPlayer(private val soundUriBase: String, val videoPlayer: VideoPla return continuation.resumeWithException(exception) } - requestAudioFocus() - continuation.ensureActive() - Timber.d("starting sound tag") - start() + if (requestAudioFocus() == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { + continuation.ensureActive() + Timber.d("starting sound tag") + start() + } else { + Timber.d("unable to get audio focus, cancelling work") + continuation.cancel() + } } } @@ -187,14 +192,15 @@ class SoundTagPlayer(private val soundUriBase: String, val videoPlayer: VideoPla prepare() } - private fun requestAudioFocus() { + @CheckResult + private fun requestAudioFocus(): Int { Timber.d("Requesting audio focus") - AudioManagerCompat.requestAudioFocus(audioManager, audioFocusRequest) + return AudioManagerCompat.requestAudioFocus(audioManager, audioFocusRequest) } - private fun abandonAudioFocus() { + private fun abandonAudioFocus(): Int { Timber.d("Abandoning audio focus") - AudioManagerCompat.abandonAudioFocusRequest(audioManager, audioFocusRequest) + return AudioManagerCompat.abandonAudioFocusRequest(audioManager, audioFocusRequest) } }