Zwei oder mehr Android-Apps können Audio gleichzeitig über denselben Ausgabestream abspielen und das System mischt alles zusammen. Das ist zwar technisch beeindruckend, kann aber für Nutzer sehr frustrierend sein. Damit nicht alle Musik-Apps gleichzeitig abgespielt werden, führt Android den Audiofokus ein. Der Audiofokus kann immer nur auf eine App festgelegt werden.
Wenn Ihre App Audio ausgeben muss, sollte sie den Audiofokus anfordern. Wenn der Fokus darauf liegt, kann er 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 aufgehoben wird. In diesem Fall sollte Ihre App die Wiedergabe pausieren oder die Lautstärke verringern, 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 zum Audiofokus einzuhalten, aber wenn eine App auf einem Gerät mit Android 11 (API-Level 30) oder niedriger auch dann laut wiedergegeben wird, wenn der Audiofokus verloren geht, kann das System dies nicht verhindern. Dieses App-Verhalten führt jedoch zu einer schlechten Nutzererfahrung und kann dazu führen, dass Nutzer die fehlerhafte App deinstallieren.
In einer gut gestalteten Audio-App sollte der Audiofokus gemäß diesen allgemeinen Richtlinien verwaltet werden:
Rufe
requestAudioFocus()
an, bevor du mit dem Spiel beginnst, und prüfe, ob du die RückrufnummerAUDIOFOCUS_REQUEST_GRANTED
erhältst. RuferequestAudioFocus()
imonPlay()
-Callback deiner Mediensitzung auf.Wenn eine andere App den Audiofokus erhält, beenden oder pausieren Sie die Wiedergabe oder senken Sie die Lautstärke.
Wenn die Wiedergabe stoppt (z. B. wenn in der App nichts mehr zu wiedergeben ist), geben Sie den Audiofokus auf. Ihre App muss den Audiofokus nicht aufgeben, wenn der Nutzer die Wiedergabe pausiert, sondern kann die Wiedergabe später fortsetzen.
Verwenden Sie
AudioAttributes
, um die Art der Audioinhalte zu beschreiben, die in Ihrer App abgespielt werden. Geben Sie für Apps, die Sprache wiedergeben, beispielsweiseCONTENT_TYPE_SPEECH
an.
Der Audiofokus wird je nach installierter Android-Version unterschiedlich behandelt:
- Android 12 (API-Level 31) oder höher
- Der Audiofokus wird vom System verwaltet. Das System blendet die Audiowiedergabe einer App aus, wenn eine andere App den Audiofokus anfordert. Außerdem wird die Audiowiedergabe stummgeschaltet, wenn ein eingehender Anruf empfangen wird.
- 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-Ebene 26) eingeführt wurden.
- Android 7.1 (API-Level 25) und niedriger
- Der Audiofokus wird nicht vom System verwaltet. Apps verwalten den Audiofokus mit den Tasten
requestAudioFocus()
undabandonAudioFocus()
.
Audiofokus unter Android 12 und höher
Eine Medien- oder Spiele-App, die den Audiofokus verwendet, sollte keine Audioinhalte abspielen, wenn der Fokus verloren geht. Unter Android 12 (API-Level 31) und höher erzwingt das System dieses Verhalten. Wenn eine App den Audiofokus anfordert, während eine andere App den Fokus hat und gerade wiedergegeben wird, wird die Wiedergabe der App erzwungen. Durch das Hinzufügen des Ausblendens wird der Übergang von einer App zur nächsten flüssiger.
Dieses Ausblenden tritt auf, wenn die folgenden Bedingungen erfüllt sind:
Die erste, derzeit wiedergegebene App erfüllt alle folgenden Kriterien:
- Die App hat entweder das Nutzungsattribut
AudioAttributes.USAGE_MEDIA
oderAudioAttributes.USAGE_GAME
. - Die App hat den Audiofokus mit
AudioManager.AUDIOFOCUS_GAIN
angefordert. - Die App spielt Audioinhalte vom Typ
AudioAttributes.CONTENT_TYPE_SPEECH
nicht ab.
- Die App hat entweder das Nutzungsattribut
Eine zweite App fordert mit
AudioManager.AUDIOFOCUS_GAIN
den Audiofokus 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 Verlust des Fokus. Die Player der App bleiben stummgeschaltet, bis die App den Audiofokus wieder anfordert.
Vorhandene Audiofokus-Verhalten
Beachte auch die folgenden Fälle, in denen der Audiofokus wechselt.
Automatisches Ducking
Die automatische Stummschaltung (vorübergehendes Heruntersetzen der Lautstärke einer App, damit eine andere besser zu hören ist) wurde in Android 8.0 (API-Ebene 26) eingeführt.
Wenn das System die Funktion implementiert, müssen Sie sie nicht in Ihrer App implementieren.
Die automatische Stummschaltung erfolgt auch, wenn eine Audiobenachrichtigung den Fokus von einer wiedergegebenen App übernimmt. Der Beginn der Benachrichtigungswiedergabe wird mit dem Ende der Ducking-Rampe synchronisiert.
Die automatische Stummschaltung wird ausgelöst, wenn die folgenden Bedingungen erfüllt sind:
Die erste, derzeit wiedergegebene App erfüllt alle folgenden Kriterien:
- Die App hat den Audiofokus mit einer beliebigen Art von Fokusgewinn angefordert.
- Die App spielt keine Audioinhalte vom Typ
AudioAttributes.CONTENT_TYPE_SPEECH
ab. - 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 den Fokus hat. Wenn die zweite App den Fokus verliert, werden sie wieder eingeblendet. Die erste App wird nicht benachrichtigt, wenn der Fokus darauf verloren geht, und muss daher nichts tun.
Hinweis: Die automatische Stummschaltung wird nicht ausgeführt, wenn der Nutzer sich Sprachinhalte anhört, da er sonst Teile des Programms verpassen könnte. Die Sprachnavigation für die Routenführung wird beispielsweise nicht gedimmt.
Aktuelle Audiowiedergabe bei eingehenden Anrufen stummschalten
Einige Apps funktionieren nicht richtig und geben während eines Anrufs weiterhin Audio wieder. In diesem Fall muss der Nutzer die betreffende App finden und stummschalten oder beenden, um den Anruf zu hören. Um dies zu verhindern, kann das System Audio von anderen Apps stummschalten, während 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 Nutzungsattribut
AudioAttributes.USAGE_MEDIA
oderAudioAttributes.USAGE_GAME
. - Die App hat den Audiofokus (beliebige Fokusgewinnung) angefordert und spielt Audio ab.
Wenn eine App während des Anrufs weiter abgespielt wird, wird die Wiedergabe stummgeschaltet, bis der Anruf beendet ist. Wenn jedoch während eines Anrufs eine App wiedergegeben wird, wird der Player nicht stummgeschaltet, da davon ausgegangen wird, dass der Nutzer die Wiedergabe absichtlich gestartet hat.
Audiofokus unter Android 8.0 bis Android 11
Ab Android 8.0 (API-Ebene 26) müssen Sie beim Aufruf von requestAudioFocus()
einen AudioFocusRequest
-Parameter angeben. Die AudioFocusRequest
enthält Informationen zum Audiokontext und zu den Funktionen Ihrer App. Das System verwendet diese Informationen, um den Gewinn und Verlust des Audiofokus automatisch zu verwalten. Wenn Sie den Audiofokus aufheben möchten, rufen Sie die Methode abandonAudioFocusRequest()
auf, die ebenfalls ein AudioFocusRequest
als Argument erwartet. Verwenden Sie dieselbe AudioFocusRequest
-Instanz, wenn Sie den Fokus anfordern und aufheben.
Verwenden Sie zum Erstellen einer AudioFocusRequest
einen AudioFocusRequest.Builder
. Da für eine Fokusanfrage immer der Anfragetyp 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 ein Pflichtfeld. Alle anderen Felder sind optional.
Method | Hinweise |
---|---|
setFocusGain()
|
Dieses Feld ist in jeder Anfrage erforderlich. Es werden dieselben Werte wie für durationHint verwendet, die vor Android 8.0 beim Aufruf von requestAudioFocus() verwendet wurden: 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 prüft, ob eine App den Audiofokus erhält oder verliert. Attribute ersetzen den Streamtyp. Ab Android 8.0 (API-Level 26) werden Streamtypen für alle Vorgänge außer der Lautstärkeregelung eingestellt. Verwende in der Fokusanfrage dieselben Attribute wie in deinem Audioplayer (siehe Beispiel nach dieser Tabelle).
Verwenden Sie zuerst ein
Wenn |
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 Ausblenden selbst vornehmen kann. Wenn du die Wiedergabe pausieren und nicht die Lautstärke senken möchtest, ruf setWillPauseWhenDucked(true) auf und erstelle und lege eine OnAudioFocusChangeListener fest, wie unter automatische Stummschaltung beschrieben.
|
setAcceptsDelayedFocusGain()
|
Eine Anfrage für den Audiofokus kann fehlschlagen, wenn der Fokus von einer anderen App gesperrt ist. Mit dieser Methode ist die verzögerte Fokusgewinnung möglich: Der Fokus kann asynchron erworben werden, sobald er verfügbar ist.
Die verzögerte Fokusgewinnung funktioniert nur, wenn Sie in der Audioanfrage auch eine |
setOnAudioFocusChangeListener()
|
Ein OnAudioFocusChangeListener ist nur erforderlich, wenn Sie in der Anfrage auch willPauseWhenDucked(true) oder setAcceptsDelayedFocusGain(true) 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 der Haupt |
Im folgenden Beispiel wird gezeigt, wie Sie mit einem AudioFocusRequest.Builder
einen AudioFocusRequest
erstellen und den Audiofokus anfordern und aufheben:
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
Wenn unter Android 8.0 (API-Ebene 26) eine andere App den Fokus mit AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
anfordert, kann das System die Lautstärke leiser stellen und wiederherstellen, ohne den onAudioFocusChange()
-Callback der App aufzurufen.
Das automatische Ducking ist für Apps zur Musik- und Videowiedergabe akzeptabel, aber nicht für die Wiedergabe gesprochener Inhalte, z. B. in einer Hörbuch-App. In diesem Fall sollte die App stattdessen pausiert werden.
Wenn Ihre App bei einer Stummschaltung pausiert werden soll, anstatt die Lautstärke zu verringern, erstellen Sie eine OnAudioFocusChangeListener
mit einer onAudioFocusChange()
-Callback-Methode, die das gewünschte Pausieren/Fortsetzen implementiert.
Rufe setOnAudioFocusChangeListener()
auf, um den Listener zu registrieren, und rufe setWillPauseWhenDucked(true)
auf, um dem System zu sagen, dass es deinen Callback verwenden soll, anstatt automatisch zu ducken.
Verzögerte Fokusgewinnung
Manchmal kann das System eine Anfrage für den Audiofokus nicht gewähren, weil der Fokus von einer anderen App „gesichert“ 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 gesetzt ist, wird für eine Anfrage, die bei gesperrtem Fokus gesendet wird, AUDIOFOCUS_REQUEST_DELAYED
zurückgegeben. Wenn die Bedingung, die den Audiofokus gesperrt hat, nicht mehr erfüllt ist, z. B. wenn ein Anruf endet, 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. Registrieren Sie dann den Listener durch Aufrufen von setOnAudioFocusChangeListener()
.
Audiofokus unter Android 7.1 und niedriger
Wenn Sie requestAudioFocus()
aufrufen, müssen Sie einen Dauerhinweis angeben, der von einer anderen App berücksichtigt werden kann, die gerade den Fokus hat und wiedergegeben wird:
- Fordere den dauerhaften Audiofokus (
AUDIOFOCUS_GAIN
) an, wenn du vorhast, in absehbarer Zeit Audioinhalte abzuspielen (z. B. Musik) und davon ausgehst, dass der vorherige Inhaber des Audiofokus die Wiedergabe beendet. - Fordere den vorübergehenden Fokus (
AUDIOFOCUS_GAIN_TRANSIENT
) an, wenn du Audio nur für kurze Zeit wiedergeben möchtest und der vorherige Inhaber die Wiedergabe pausieren soll. - Fordere den vorübergehenden Fokus mit Ducking (
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
) an, um anzugeben, dass du Audio nur für kurze Zeit abspielen möchtest und dass der vorherige Fokusinhaber die Wiedergabe fortsetzen darf, wenn er seine Audioausgabe leiser stellt. Beide Audioausgaben werden in den Audiostream eingemischt. Ducking eignet sich besonders für Apps, bei denen der Audiostream nur zeitweise verwendet wird, z. B. für hörbare Navigationsanweisungen.
Für die Methode requestAudioFocus()
ist außerdem eine AudioManager.OnAudioFocusChangeListener
erforderlich. Dieser Listener sollte in derselben Aktivität oder demselben Dienst erstellt werden, zu dem Ihre Mediensitzung gehört. Es implementiert den Rückruf onAudioFocusChange()
, den Ihre App erhält, wenn eine andere App den Audiofokus erhält oder aufgibt.
Im folgenden Snippet wird der dauerhafte Audiofokus auf den Stream STREAM_MUSIC
angefordert und ein OnAudioFocusChangeListener
registriert, um nachfolgende Änderungen des Audiofokus zu verarbeiten. (Der Änderungslistener 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 Sie die Wiedergabe beendet haben, 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 den vorübergehenden Fokus angefordert haben, wird eine App, die pausiert oder stummgeschaltet wurde, 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 wird in Ihrer App die Methode onAudioFocusChange()
im AudioFocusChangeListener
aufgerufen, das Sie beim Aufrufen von requestAudioFocus()
angegeben haben.
Der an onAudioFocusChange()
übergebene Parameter focusChange
gibt die Art der Änderung an. Er entspricht dem Dauerhinweis, der von der App verwendet wird, die den Fokus erhält. Ihre App sollte entsprechend reagieren.
- Vorübergehender Fokusverlust
-
Wenn die Fokusänderung vorübergehend ist (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK
oderAUDIOFOCUS_LOSS_TRANSIENT
), sollte Ihre App die Lautstärke reduzieren (sofern Sie nicht auf die automatische Stummschaltung zurückgreifen) oder die Wiedergabe pausieren, aber ansonsten denselben Status beibehalten.Bei einem vorübergehenden Verlust des Audiofokus solltest du die Änderungen am Audiofokus weiterhin beobachten und bereit sein, die normale Wiedergabe fortzusetzen, sobald der Fokus wiederhergestellt ist. Wenn die blockierende App den Fokus verliert, erhalten Sie einen Rückruf (
AUDIOFOCUS_GAIN
). Jetzt können Sie die Lautstärke wieder auf das normale Niveau bringen oder die Wiedergabe fortsetzen. - Dauerhafter Verlust des Fokus
-
Wenn der Audiofokus dauerhaft verloren geht (
AUDIOFOCUS_LOSS
), spielt eine andere App Audioinhalte ab. Deine App sollte die Wiedergabe sofort pausieren, da sie keinenAUDIOFOCUS_GAIN
-Callback erhält. Wenn die Wiedergabe fortgesetzt werden soll, muss der Nutzer eine explizite Aktion ausführen, z. B. die Wiedergabesteuerung in einer Benachrichtigung oder App-Benutzeroberfläche drücken.
Das folgende Code-Snippet zeigt, wie OnAudioFocusChangeListener
und sein onAudioFocusChange()
-Callback implementiert werden. Beachten Sie, dass mit Handler
der Rückruf bei Beendigung bei dauerhaftem Verlust des Audiofokus verzögert wird.
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, rufe mHandler.removeCallbacks(mDelayedStopRunnable)
als Reaktion auf Statusänderungen auf. Rufen Sie removeCallbacks()
beispielsweise in onPlay()
, onSkipToNext()
usw. Ihres Callbacks auf. Sie sollten diese Methode auch im onDestroy()
-Callback Ihres Dienstes aufrufen, wenn Sie die vom Dienst verwendeten Ressourcen bereinigen.