Zwei oder mehr Android-Apps können gleichzeitig Audio auf denselben Ausgabestream ausgeben. Das System mischt alles zusammen. Das ist zwar technisch beeindruckend, kann aber für Nutzer sehr ärgerlich sein. Damit nicht alle Musik-Apps gleichzeitig wiedergegeben werden, gibt es in Android das Konzept des Audio-Fokus. Es kann immer nur eine App den Audiofokus haben.
Wenn Ihre App Audio ausgeben muss, sollte sie den Audiofokus anfordern. Wenn es den Fokus hat, kann es Ton wiedergeben. Nachdem Sie den Audiofokus erhalten haben, können Sie ihn möglicherweise nicht bis zum Ende der Wiedergabe beibehalten. Eine andere App kann den Fokus anfordern, wodurch Ihr Audiofokus unterbrochen wird. In diesem Fall sollte die Wiedergabe in Ihrer App pausiert oder die Lautstärke verringert werden, damit Nutzer die neue Audioquelle besser hören können.
Vor Android 12 (API-Level 31) wird der Audiofokus nicht vom System verwaltet. App-Entwickler werden zwar aufgefordert, die Richtlinien für den Audiofokus einzuhalten, aber wenn eine App weiterhin laut wiedergegeben wird, nachdem sie den Audiofokus auf einem Gerät mit Android 11 (API-Level 30) oder niedriger verloren hat, kann das System dies nicht verhindern. Dieses App-Verhalten führt jedoch zu einer schlechten Nutzererfahrung und kann dazu führen, dass Nutzer die App deinstallieren.
Eine gut gestaltete Audio-App sollte den Audiofokus gemäß den folgenden allgemeinen Richtlinien verwalten:
Rufen Sie
requestAudioFocus()
unmittelbar vor Spielbeginn an und prüfen Sie, ob der AnrufAUDIOFOCUS_REQUEST_GRANTED
zurückgibt. Rufen SierequestAudioFocus()
imonPlay()
-Callback Ihrer Mediensitzung auf.Wenn eine andere App den Audiofokus erhält, beenden oder pausieren Sie die Wiedergabe oder verringern Sie die Lautstärke.
Wenn die Wiedergabe beendet wird (z. B. wenn die App nichts mehr wiederzugeben hat), gib den Audiofokus auf. Ihre App muss den Audiofokus nicht aufgeben, wenn der Nutzer die Wiedergabe pausiert, aber möglicherweise später fortsetzt.
Verwenden Sie
AudioAttributes
, um den Audiotyp zu beschreiben, der in Ihrer App wiedergegeben wird. Geben Sie beispielsweise für Apps, die Sprache wiedergeben,CONTENT_TYPE_SPEECH
an.
Die Audiofokussierung wird je nach Android-Version unterschiedlich gehandhabt:
- Android 12 (API‑Level 31) oder höher
- Der Audiofokus wird vom System verwaltet. Das System erzwingt, dass die Audiowiedergabe einer App ausgeblendet wird, wenn eine andere App den Audiofokus anfordert. Das System schaltet die Audiowiedergabe auch stumm, wenn ein eingehender Anruf eingeht.
- Android 8.0 (API-Level 26) bis Android 11 (API-Level 30)
- Der Audiofokus wird nicht vom System verwaltet, umfasst aber einige Änderungen, die ab Android 8.0 (API-Level 26) eingeführt wurden.
- Android 7.1 (API-Level 25) und niedriger
- Der Audiofokus wird nicht vom System verwaltet, sondern von Apps über
requestAudioFocus()
undabandonAudioFocus()
.
Audio-Fokus in Android 12 und höher
Eine Media- oder Spiele-App, die den Audiofokus verwendet, sollte nach dem Verlust des Fokus keine Audioinhalte mehr wiedergeben. Unter Android 12 (API-Level 31) und höher wird dieses Verhalten vom System erzwungen. Wenn eine App den Audiofokus anfordert, während eine andere App den Fokus hat und Audioinhalte wiedergibt, zwingt das System die wiedergebende App, die Lautstärke zu verringern. Durch das Einblenden wird der Übergang von einer App zur anderen flüssiger.
Dieses Ausblendverhalten tritt auf, wenn die folgenden Bedingungen erfüllt sind:
Die erste App, die gerade wiedergegeben wird, erfüllt alle diese Kriterien:
- Die App hat entweder das Attribut
AudioAttributes.USAGE_MEDIA
oderAudioAttributes.USAGE_GAME
. - Die App hat den Audiofokus mit
AudioManager.AUDIOFOCUS_GAIN
angefordert. - Die App gibt keine Audioinhalte mit dem Inhaltstyp
AudioAttributes.CONTENT_TYPE_SPEECH
wieder.
- Die App hat entweder das Attribut
Eine zweite App fordert den Audiofokus mit
AudioManager.AUDIOFOCUS_GAIN
an.
Wenn diese Bedingungen erfüllt sind, blendet das Audiosystem die erste App aus. Am Ende des Ausblendens benachrichtigt das System die erste App über den Fokusverlust. Die Player der App bleiben stummgeschaltet, bis die App den Audiofokus wieder anfordert.
Vorhandenes Audiofokusverhalten
Außerdem sollten Sie diese anderen Fälle kennen, in denen der Audiofokus wechselt.
Automatisches Ducking
Die automatische Pegelabsenkung (vorübergehendes Verringern des Audiopegels einer App, damit eine andere App deutlich zu hören ist) wurde in Android 8.0 (API-Level 26) eingeführt.
Wenn das System Ducking implementiert, müssen Sie Ducking nicht in Ihrer App implementieren.
Die automatische Pegelabsenkung erfolgt auch, wenn eine Audiobenachrichtigung den Fokus von einer App übernimmt, die gerade wiedergegeben wird. Der Beginn der Benachrichtigungswiedergabe wird mit dem Ende der Pegelabsenkungsrampe synchronisiert.
Die automatische Absenkung erfolgt, wenn die folgenden Bedingungen erfüllt sind:
Die erste App, die gerade wiedergegeben wird, erfüllt alle diese Kriterien:
- Die App hat erfolgreich den Audio-Fokus mit einer beliebigen Art von Fokus-Gain angefordert.
- Die App gibt keine Audioinhalte mit dem Inhaltstyp
AudioAttributes.CONTENT_TYPE_SPEECH
wieder. - Die App hat
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)
nicht festgelegt.
Eine zweite App fordert den Audiofokus mit
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
an.
Wenn diese Bedingungen erfüllt sind, dämpft das Audiosystem alle aktiven Player der ersten App, während die zweite App im Fokus ist. Wenn die zweite App den Fokus verliert, werden sie wieder angedockt. Die erste App wird nicht benachrichtigt, wenn sie den Fokus verliert, muss also nichts tun.
Hinweis: Wenn der Nutzer Sprachinhalte hört, wird die automatische Absenkung nicht durchgeführt, da er sonst möglicherweise einen Teil des Programms verpasst. Die Sprachnavigation für Routen wird beispielsweise nicht unterbrochen.
Aktuelle Audiowiedergabe bei eingehenden Anrufen stummschalten
Einige Apps verhalten sich nicht richtig und geben während Telefonanrufen weiterhin Audio wieder. In dieser Situation muss der Nutzer die störende App suchen und stummschalten oder beenden, um den Anruf hören zu können. Um dies zu verhindern, kann das System Audio von anderen Apps stummschalten, wenn ein Anruf eingeht. Das System ruft diese Funktion auf, wenn ein eingehender Anruf empfangen wird und eine App die folgenden Bedingungen erfüllt:
- Die App hat entweder das Attribut
AudioAttributes.USAGE_MEDIA
oderAudioAttributes.USAGE_GAME
. - Die App hat erfolgreich den Audiofokus angefordert (jede Art von Fokusgewinn) und gibt Audio wieder.
Wenn eine App während des Anrufs weiter abgespielt wird, wird die Wiedergabe stummgeschaltet, bis der Anruf beendet ist. Wenn jedoch während des Anrufs die Wiedergabe in einer App gestartet wird, wird der Player nicht stummgeschaltet, da davon ausgegangen wird, dass der Nutzer die Wiedergabe absichtlich gestartet hat.
Audiofokus in Android 8.0 bis Android 11
Ab Android 8.0 (API-Level 26) müssen Sie beim Aufrufen von requestAudioFocus()
einen AudioFocusRequest
-Parameter angeben. Das AudioFocusRequest
enthält Informationen zum Audiokontext und zu den Funktionen Ihrer App. Das System verwendet diese Informationen, um die Verstärkung und den Verlust des Audiofokus automatisch zu verwalten. Rufen Sie zum Freigeben des Audiofokus die Methode abandonAudioFocusRequest()
auf, die auch ein AudioFocusRequest
als Argument akzeptiert. Verwenden Sie dieselbe AudioFocusRequest
-Instanz, wenn Sie den Fokus anfordern und aufgeben.
Zum Erstellen eines AudioFocusRequest
verwenden Sie ein AudioFocusRequest.Builder
. Da in einer Fokusanfrage immer der Typ der Anfrage angegeben werden muss, ist der Typ im Konstruktor für den Builder enthalten. Verwenden Sie die Methoden des Builders, um die anderen Felder der Anfrage festzulegen.
Das Feld FocusGain
ist erforderlich. Alle anderen Felder sind optional.
Method | Hinweise |
---|---|
setFocusGain()
|
Dieses Feld ist in jeder Anfrage erforderlich. Es verwendet dieselben Werte wie durationHint im Aufruf von requestAudioFocus() vor Android 8.0: AUDIOFOCUS_GAIN , AUDIOFOCUS_GAIN_TRANSIENT , AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK oder AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE .
|
setAudioAttributes()
|
AudioAttributes beschreibt den Anwendungsfall für Ihre App. Das System berücksichtigt diese, wenn eine App den Audiofokus erhält oder verliert. Attribute ersetzen den Begriff „Streamtyp“. In Android 8.0 (API-Level 26) und höher sind Streamtypen für alle Vorgänge außer Lautstärkeregelungen veraltet. Verwende in der Fokusanfrage dieselben Attribute wie in deinem Audioplayer (siehe Beispiel nach dieser Tabelle).
Geben Sie zuerst die Attribute mit einem
Wenn nicht angegeben, wird standardmäßig |
setWillPauseWhenDucked()
|
Wenn eine andere App den Fokus mit AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK anfordert, erhält die App, die den Fokus hat, in der Regel keinen onAudioFocusChange() -Callback, da das System das Ducking selbst ausführen kann. Wenn Sie die Wiedergabe pausieren und nicht die Lautstärke verringern möchten, rufen Sie setWillPauseWhenDucked(true) auf und erstellen und legen Sie ein OnAudioFocusChangeListener fest, wie unter Automatische Lautstärkereduzierung beschrieben.
|
setAcceptsDelayedFocusGain()
|
Eine Anfrage für den Audiofokus kann fehlschlagen, wenn der Fokus von einer anderen App gesperrt wird.
Diese Methode ermöglicht die verzögerte Fokussierung: die Möglichkeit, den Fokus asynchron zu erlangen, wenn er verfügbar wird.
Die verzögerte Fokusübernahme funktioniert nur, wenn Sie auch ein |
setOnAudioFocusChangeListener()
|
Ein OnAudioFocusChangeListener ist nur erforderlich, wenn Sie auch willPauseWhenDucked(true) oder setAcceptsDelayedFocusGain(true) in der Anfrage angeben.
Es gibt zwei Methoden zum Festlegen des Listeners: eine mit und eine ohne Handler-Argument. Der Handler ist der Thread, in dem der Listener ausgeführt wird. Wenn Sie keinen Handler angeben, wird der Handler verwendet, der mit dem Haupt- |
Das folgende Beispiel zeigt, wie Sie ein AudioFocusRequest.Builder
verwenden, um ein AudioFocusRequest
zu erstellen und den Audiofokus anzufordern und aufzugeben:
Kotlin
// initializing variables for audio focus and playback management audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).run { setAudioAttributes(AudioAttributes.Builder().run { setUsage(AudioAttributes.USAGE_GAME) setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) build() }) setAcceptsDelayedFocusGain(true) setOnAudioFocusChangeListener(afChangeListener, handler) build() } val focusLock = Any() var playbackDelayed = false var playbackNowAuthorized = false // requesting audio focus and processing the response val res = audioManager.requestAudioFocus(focusRequest) synchronized(focusLock) { playbackNowAuthorized = when (res) { AudioManager.AUDIOFOCUS_REQUEST_FAILED -> false AudioManager.AUDIOFOCUS_REQUEST_GRANTED -> { playbackNow() true } AudioManager.AUDIOFOCUS_REQUEST_DELAYED -> { playbackDelayed = true false } else -> false } } // implementing OnAudioFocusChangeListener to react to focus changes override fun onAudioFocusChange(focusChange: Int) { when (focusChange) { AudioManager.AUDIOFOCUS_GAIN -> if (playbackDelayed || resumeOnFocusGain) { synchronized(focusLock) { playbackDelayed = false resumeOnFocusGain = false } playbackNow() } AudioManager.AUDIOFOCUS_LOSS -> { synchronized(focusLock) { resumeOnFocusGain = false playbackDelayed = false } pausePlayback() } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> { synchronized(focusLock) { // only resume if playback is being interrupted resumeOnFocusGain = isPlaying() playbackDelayed = false } pausePlayback() } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> { // ... pausing or ducking depends on your app } } }
Java
// initializing variables for audio focus and playback management audioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE); playbackAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_GAME) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build(); focusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN) .setAudioAttributes(playbackAttributes) .setAcceptsDelayedFocusGain(true) .setOnAudioFocusChangeListener(afChangeListener, handler) .build(); final Object focusLock = new Object(); boolean playbackDelayed = false; boolean playbackNowAuthorized = false; // requesting audio focus and processing the response int res = audioManager.requestAudioFocus(focusRequest); synchronized(focusLock) { if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { playbackNowAuthorized = false; } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { playbackNowAuthorized = true; playbackNow(); } else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) { playbackDelayed = true; playbackNowAuthorized = false; } } // implementing OnAudioFocusChangeListener to react to focus changes @Override public void onAudioFocusChange(int focusChange) { switch (focusChange) { case AudioManager.AUDIOFOCUS_GAIN: if (playbackDelayed || resumeOnFocusGain) { synchronized(focusLock) { playbackDelayed = false; resumeOnFocusGain = false; } playbackNow(); } break; case AudioManager.AUDIOFOCUS_LOSS: synchronized(focusLock) { resumeOnFocusGain = false; playbackDelayed = false; } pausePlayback(); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: synchronized(focusLock) { // only resume if playback is being interrupted resumeOnFocusGain = isPlaying(); playbackDelayed = false; } pausePlayback(); break; case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // ... pausing or ducking depends on your app break; } } }
Automatisches Ducking
Unter Android 8.0 (API-Level 26) kann das System die Lautstärke verringern und wiederherstellen, ohne den onAudioFocusChange()
-Callback der App aufzurufen, wenn eine andere App den Fokus mit AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
anfordert.
Das automatische Absenken der Lautstärke ist für Musik- und Videowiedergabe-Apps akzeptabel, aber nicht sinnvoll, wenn gesprochene Inhalte wiedergegeben werden, z. B. in einer Hörbuch-App. In diesem Fall sollte die App stattdessen pausieren.
Wenn Ihre App pausieren soll, wenn sie aufgefordert wird, die Lautstärke zu verringern, anstatt die Lautstärke zu verringern, erstellen Sie ein OnAudioFocusChangeListener
mit einer onAudioFocusChange()
-Callback-Methode, die das gewünschte Pausen-/Fortsetzungsverhalten implementiert.
Rufen Sie setOnAudioFocusChangeListener()
auf, um den Listener zu registrieren, und rufen Sie setWillPauseWhenDucked(true)
auf, um dem System mitzuteilen, dass Ihr Callback verwendet werden soll und keine automatische Absenkung erfolgen soll.
Verzögerter Fokus
Manchmal kann das System eine Anfrage für den Audiofokus nicht gewähren, weil der Fokus von einer anderen App „gesperrt“ ist, z. B. während eines Anrufs. In diesem Fall gibt requestAudioFocus()
AUDIOFOCUS_REQUEST_FAILED
zurück. In diesem Fall sollte Ihre App die Audiowiedergabe nicht fortsetzen, da sie nicht den Fokus erhalten hat.
Die Methode setAcceptsDelayedFocusGain(true)
, mit der Ihre App eine Anfrage für den Fokus asynchron verarbeiten kann. Wenn dieses Flag festgelegt ist, wird bei einer Anfrage, die gestellt wird, wenn der Fokus gesperrt ist, AUDIOFOCUS_REQUEST_DELAYED
zurückgegeben. Wenn die Bedingung, die den Audiofokus gesperrt hat, nicht mehr vorhanden ist, z. B. wenn ein Telefonanruf beendet wird, gewährt das System die ausstehende Fokusanfrage und ruft onAudioFocusChange()
auf, um Ihre App zu benachrichtigen.
Um die verzögerte Fokussierung zu verarbeiten, müssen Sie ein OnAudioFocusChangeListener
mit einer onAudioFocusChange()
-Callback-Methode erstellen, die das gewünschte Verhalten implementiert, und den Listener registrieren, indem Sie setOnAudioFocusChangeListener()
aufrufen.
Audiofokus in Android 7.1 und niedriger
Wenn Sie requestAudioFocus()
aufrufen, müssen Sie einen Hinweis zur Dauer angeben, der möglicherweise von einer anderen App berücksichtigt wird, die derzeit den Fokus hat und die Wiedergabe steuert:
- Fordern Sie den dauerhaften Audiofokus (
AUDIOFOCUS_GAIN
) an, wenn Sie Audio für die absehbare Zukunft abspielen möchten (z. B. beim Abspielen von Musik) und Sie erwarten, dass der vorherige Inhaber des Audiofokus die Wiedergabe beendet. - Fordern Sie den vorübergehenden Fokus (
AUDIOFOCUS_GAIN_TRANSIENT
) an, wenn Sie Audio nur für kurze Zeit wiedergeben möchten und erwarten, dass der vorherige Inhaber die Wiedergabe pausiert. - Fordern Sie mit ducking (
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
) einen vorübergehenden Fokus an, um anzugeben, dass Sie Audio nur für kurze Zeit abspielen möchten und dass der vorherige Fokusinhaber weiterhin Audio abspielen kann, wenn er seine Audioausgabe „duckt“ (verringert). Beide Audioausgaben werden in den Audiostream gemischt. Ducking eignet sich besonders für Apps, die den Audiostream nur zeitweise verwenden, z. B. für hörbare Routenanweisungen.
Für die Methode requestAudioFocus()
ist auch ein AudioManager.OnAudioFocusChangeListener
erforderlich. Dieser Listener sollte in derselben Aktivität oder demselben Dienst erstellt werden, zu dem deine Mediensitzung gehört. Sie implementiert den Callback onAudioFocusChange()
, den Ihre App empfängt, wenn eine andere App den Audiofokus erhält oder aufgibt.
Im folgenden Snippet wird der permanente Audiofokus für den Stream STREAM_MUSIC
angefordert und ein OnAudioFocusChangeListener
registriert, um nachfolgende Änderungen des Audiofokus zu verarbeiten. Der Change-Listener wird unter Auf eine Änderung des Audiofokus reagieren beschrieben.
Kotlin
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager lateinit var afChangeListener AudioManager.OnAudioFocusChangeListener ... // Request audio focus for playback val result: Int = audioManager.requestAudioFocus( afChangeListener, // Use the music stream. AudioManager.STREAM_MUSIC, // Request permanent focus. AudioManager.AUDIOFOCUS_GAIN ) if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // Start playback }
Java
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); AudioManager.OnAudioFocusChangeListener afChangeListener; ... // Request audio focus for playback int result = audioManager.requestAudioFocus(afChangeListener, // Use the music stream. AudioManager.STREAM_MUSIC, // Request permanent focus. AudioManager.AUDIOFOCUS_GAIN); if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { // Start playback }
Wenn die Wiedergabe beendet ist, rufen Sie
abandonAudioFocus()
auf.
Kotlin
audioManager.abandonAudioFocus(afChangeListener)
Java
// Abandon audio focus when playback complete audioManager.abandonAudioFocus(afChangeListener);
Dadurch wird das System darüber informiert, dass Sie den Fokus nicht mehr benötigen, und die zugehörige OnAudioFocusChangeListener
wird abgemeldet. Wenn Sie einen vorübergehenden Fokus angefordert haben, wird eine pausierte oder gedämpfte App benachrichtigt, dass sie die Wiedergabe fortsetzen oder die Lautstärke wiederherstellen kann.
Auf eine Änderung des Audiofokus reagieren
Wenn eine App den Audiofokus erhält, muss sie ihn freigeben können, wenn eine andere App den Audiofokus für sich anfordert. In diesem Fall erhält Ihre App einen Aufruf der Methode onAudioFocusChange()
im AudioFocusChangeListener
, den Sie angegeben haben, als die App requestAudioFocus()
aufgerufen hat.
Der an onAudioFocusChange()
übergebene Parameter focusChange
gibt die Art der Änderung an. Sie entspricht dem von der App, die den Fokus erhält, verwendeten Dauerhinweis. Ihre App sollte entsprechend reagieren.
- Vorübergehender Verlust des Fokus
-
Wenn sich der Fokus nur vorübergehend ändert (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
oderAUDIOFOCUS_LOSS_TRANSIENT
), sollte Ihre App die Wiedergabe leiser stellen (wenn Sie nicht automatisches Leiserstellen verwenden) oder pausieren, aber ansonsten den gleichen Status beibehalten.Bei einem vorübergehenden Verlust des Audiofokus sollten Sie weiterhin Änderungen des Audiofokus beobachten und bereit sein, die normale Wiedergabe fortzusetzen, wenn Sie den Fokus wiedererlangen. Wenn die blockierende App den Fokus verliert, erhalten Sie einen Callback (
AUDIOFOCUS_GAIN
). An diesem Punkt können Sie die Lautstärke auf das normale Niveau zurücksetzen oder die Wiedergabe neu starten. - Permanenter Verlust des Fokus
-
Wenn der Audiofokus dauerhaft verloren geht (
AUDIOFOCUS_LOSS
), gibt eine andere App Audioinhalte wieder. Ihre App sollte die Wiedergabe sofort pausieren, da sie niemals einenAUDIOFOCUS_GAIN
-Callback erhält. Um die Wiedergabe neu zu starten, muss der Nutzer eine explizite Aktion ausführen, z. B. in einer Benachrichtigung oder App-Benutzeroberfläche auf die Schaltfläche „Wiedergabe“ tippen.
Das folgende Code-Snippet zeigt, wie Sie die OnAudioFocusChangeListener
-Methode und den zugehörigen onAudioFocusChange()
-Callback implementieren. Beachten Sie die Verwendung von Handler
, um den Stop-Callback bei einem dauerhaften Verlust des Audiofokus zu verzögern.
Kotlin
private val handler = Handler() private val afChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange -> when (focusChange) { AudioManager.AUDIOFOCUS_LOSS -> { // Permanent loss of audio focus // Pause playback immediately mediaController.transportControls.pause() // Wait 30 seconds before stopping playback handler.postDelayed(delayedStopRunnable, TimeUnit.SECONDS.toMillis(30)) } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> { // Pause playback } AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> { // Lower the volume, keep playing } AudioManager.AUDIOFOCUS_GAIN -> { // Your app has been granted audio focus again // Raise volume to normal, restart playback if necessary } } }
Java
private Handler handler = new Handler(); AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() { public void onAudioFocusChange(int focusChange) { if (focusChange == AudioManager.AUDIOFOCUS_LOSS) { // Permanent loss of audio focus // Pause playback immediately mediaController.getTransportControls().pause(); // Wait 30 seconds before stopping playback handler.postDelayed(delayedStopRunnable, TimeUnit.SECONDS.toMillis(30)); } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) { // Pause playback } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) { // Lower the volume, keep playing } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { // Your app has been granted audio focus again // Raise volume to normal, restart playback if necessary } } };
Der Handler verwendet eine Runnable
, die so aussieht:
Kotlin
private var delayedStopRunnable = Runnable { mediaController.transportControls.stop() }
Java
private Runnable delayedStopRunnable = new Runnable() { @Override public void run() { getMediaController().getTransportControls().stop(); } };
Damit die verzögerte Beendigung nicht ausgelöst wird, wenn der Nutzer die Wiedergabe neu startet, rufen Sie mHandler.removeCallbacks(mDelayedStopRunnable)
als Reaktion auf alle Statusänderungen auf. Rufen Sie beispielsweise removeCallbacks()
im onPlay()
-, onSkipToNext()
-Callback usw. auf. Sie sollten diese Methode auch im onDestroy()
-Callback Ihres Dienstes aufrufen, wenn Sie die von Ihrem Dienst verwendeten Ressourcen bereinigen.