Zwei oder mehr Android-Apps können gleichzeitig Audioinhalte an denselben Ausgabestream senden und das System mischt alles zusammen. Das ist zwar technisch beeindruckend, kann aber für Nutzer sehr störend sein. Damit nicht alle Musik-Apps gleichzeitig wiedergegeben werden, wurde in Android das Konzept des Audiofokus eingeführt. Nur eine App kann jeweils den Audiofokus haben.
Wenn Ihre App Audioinhalte ausgeben muss, sollte sie den Audiofokus anfordern. Wenn sie den Fokus hat, kann sie Audioinhalte wiedergeben. Nachdem Sie den Audiofokus erhalten haben, können Sie ihn jedoch möglicherweise nicht behalten, bis die Wiedergabe beendet ist. Eine andere App kann den Fokus anfordern, wodurch Ihre App den Audiofokus verliert. In diesem Fall sollte Ihre App die Wiedergabe pausieren oder die Lautstärke verringern, damit Nutzer die neue Audioquelle leichter 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, obwohl 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 oft dazu führen, dass Nutzer die App deinstallieren.
Eine gut entwickelte Audio-App sollte den Audiofokus gemäß diesen allgemeinen Richtlinien verwalten:
Rufen Sie
requestAudioFocus()unmittelbar vor Beginn der Wiedergabe auf und prüfen Sie, ob der AufrufAUDIOFOCUS_REQUEST_GRANTEDzurü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 wiedergeben kann), geben Sie den Audiofokus auf. Ihre App muss den Audiofokus nicht aufgeben, wenn der Nutzer die Wiedergabe pausiert, sie aber später fortsetzen möchte.
Verwenden Sie
AudioAttributes, um den Typ der Audioinhalte zu beschreiben, die Ihre App wiedergibt. Geben Sie beispielsweise für Apps, die Sprache wiedergeben, geben Sie anCONTENT_TYPE_SPEECH.
Der Audiofokus wird je nach der ausgeführten 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 eingeht.
- Android 8.0 (API-Level 26) bis Android 11 (API-Level 30)
- Der Audiofokus wird nicht vom System verwaltet, aber es gibt 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 und Apps verwalten den Audiofokus mit
requestAudioFocus()undabandonAudioFocus().
Audiofokus in Android 12 und höher
Eine Medien- oder Spiele-App, die den Audiofokus verwendet, sollte keine Audioinhalte wiedergeben, nachdem sie den Fokus verloren hat. 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 Audioinhalte wiedergibt, blendet das System die Wiedergabe der App aus. Durch das Ausblenden wird ein reibungsloserer Übergang von einer App zu einer anderen ermöglicht.
Dieses Ausblenden erfolgt, wenn die folgenden Bedingungen erfüllt sind:
Die erste, derzeit wiedergebende App erfüllt alle folgenden Kriterien:
- Die App hat entweder das
AudioAttributes.USAGE_MEDIAoder dasAudioAttributes.USAGE_GAMENutzungsattribut. - Die App hat den Audiofokus mit
AudioManager.AUDIOFOCUS_GAINangefordert. - Die App gibt keine Audioinhalte mit dem Inhaltstyp
AudioAttributes.CONTENT_TYPE_SPEECHwieder.
- Die App hat entweder das
Eine zweite App fordert den Audiofokus mit
AudioManager.AUDIOFOCUS_GAINan.
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 Verhaltensweisen des Audiofokus
Sie sollten auch diese anderen Fälle kennen, in denen der Audiofokus wechselt.
Automatisches Ducking
Das automatische Ducking (vorübergehendes Verringern der Lautstärke einer App, damit eine andere App deutlich zu hören ist) wurde in Android 8.0 (API-Level 26) eingeführt.
Wenn das System das Ducking implementiert, müssen Sie es nicht in Ihrer App implementieren.
Automatisches Ducking erfolgt auch, wenn eine Audiobenachrichtigung den Fokus von einer wiedergebenden App übernimmt. Der Beginn der Wiedergabe der Benachrichtigung wird mit dem Ende der Ducking-Rampe synchronisiert.
Automatisches Ducking erfolgt, wenn die folgenden Bedingungen erfüllt sind:
Die erste, derzeit wiedergebende App erfüllt alle folgenden Kriterien:
- Die App hat den Audiofokus mit einer beliebigen Art von Fokus Gewinn angefordert.
- Die App gibt keine Audioinhalte mit dem Inhaltstyp
AudioAttributes.CONTENT_TYPE_SPEECHwieder. - Die App hat
AudioFocusRequest.Builder.setWillPauseWhenDucked(true)nicht festgelegt.
Eine zweite App fordert den Audiofokus mit
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCKan.
Wenn diese Bedingungen erfüllt sind, verringert das Audiosystem die Lautstärke aller aktiven Player der ersten App, während die zweite App den Fokus hat. Wenn die zweite App den Fokus aufgibt, wird die Lautstärke wieder erhöht. Die erste App wird nicht benachrichtigt, wenn sie den Fokus verliert, daher muss sie nichts tun.
Automatisches Ducking wird nicht ausgeführt, wenn der Nutzer Sprachinhalte hört, da er sonst möglicherweise einen Teil des Programms verpasst. Beispielsweise wird die Sprachführung für Routenbeschreibungen nicht verringert.
Aktuelle Audiowiedergabe für eingehende Anrufe stummschalten
Einige Apps verhalten sich nicht richtig und geben während Anrufen weiterhin Audioinhalte wieder. In diesem Fall muss der Nutzer die betreffende App suchen und stummschalten oder beenden, um den Anruf zu hören. Um dies zu verhindern, kann das System Audioinhalte von anderen Apps stummschalten, während ein eingehender Anruf eingeht. Das System ruft diese Funktion auf, wenn ein eingehender Anruf eingeht und eine App diese Bedingungen erfüllt:
- Die App hat entweder das Nutzungsattribut
AudioAttributes.USAGE_MEDIAoderAudioAttributes.USAGE_GAME. - Die App hat den Audiofokus angefordert (beliebiger Fokusgewinn) und gibt Audioinhalte wieder.
Wenn eine App während des Anrufs weiterhin Audioinhalte wiedergibt, wird die Wiedergabe stummgeschaltet, bis der Anruf beendet ist. Wenn eine App jedoch während des Anrufs mit der Wiedergabe beginnt, 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. 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. Um den Audiofokus freizugeben, rufen Sie die Methode
abandonAudioFocusRequest()
auf, die ebenfalls ein AudioFocusRequest als Argument verwendet. Verwenden Sie dieselbe AudioFocusRequest-Instanz, wenn Sie den Fokus anfordern und aufgeben.
Verwenden Sie
AudioFocusRequest.Builder, um eine AudioFocusRequest zu erstellen. Da bei einer Fokusanforderung immer der Typ der Anforderung angegeben werden muss, ist der Typ im Konstruktor für den Builder enthalten. Verwenden Sie die Methoden des Builders, um die anderen Felder der Anforderung festzulegen.
Das Feld FocusGain ist erforderlich. Alle anderen Felder sind optional.
| Methode | Hinweise |
|---|---|
setFocusGain()
|
Dieses Feld ist in jeder Anfrage erforderlich. Es verwendet dieselben Werte wie
das durationHint, das im Aufruf von requestAudioFocus() vor Android 8.0 verwendet wurde:
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 Attribute, wenn eine App den Audiofokus erhält und verliert. Attribute ersetzen den Begriff des Streamtyps. In Android 8.0 (API-Level 26) und höher sind Streamtypen für alle Vorgänge außer Lautstärkeregelungen veraltet. Verwenden Sie in der Fokusanforderung dieselben Attribute, die Sie in Ihrem Audioplayer verwenden (wie im Beispiel nach dieser Tabelle gezeigt).
Geben Sie zuerst die Attribute mit
Wenn nichts angegeben ist, wird für |
setWillPauseWhenDucked()
|
Wenn eine andere App den Fokus mit
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK anfordert, erhält die App, die den Fokus hat, normalerweise 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 einenOnAudioFocusChangeListener fest, wie unter automatisches Ducking beschrieben.
|
setAcceptsDelayedFocusGain()
|
Eine Anfrage für den Audiofokus kann fehlschlagen, wenn der Fokus von einer anderen App gesperrt ist.
Mit dieser Methode kann der Fokus verzögert gewonnen werden: Der Fokus kann asynchron erfasst werden, wenn er verfügbar wird.
Beachten Sie, dass der verzögerte Fokusgewinn nur funktioniert, wenn Sie in der Audioanfrage auch einen |
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 dem Haupt- |
Im folgenden Beispiel wird gezeigt, wie Sie mit AudioFocusRequest.Builder eine
AudioFocusRequest erstellen und den Audiofokus anfordern und aufgeben:
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 in Android 8.0 (API-Level 26) eine andere App den Fokus mit AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK anfordert, kann das System die Lautstärke verringern und wiederherstellen, ohne den onAudioFocusChange()-Callback der App aufzurufen.
Automatisches Ducking ist zwar für Musik- und Videowiedergabe-Apps akzeptabel, aber nicht nützlich, 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, und nicht die Lautstärke verringern soll, erstellen Sie einen OnAudioFocusChangeListener mit einer onAudioFocusChange()-Callback-Methode, die das gewünschte Verhalten beim Pausieren und Fortsetzen 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, anstatt automatisches Ducking auszuführen.
Verzögerter Fokusgewinn
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. Wenn dies geschieht, sollte Ihre App die Audiowiedergabe nicht fortsetzen, da sie den Fokus nicht erhalten hat.
Die Methode setAcceptsDelayedFocusGain(true) ermöglicht es Ihrer App, eine Fokusanforderung
asynchron zu verarbeiten. Wenn dieses Flag festgelegt ist, gibt eine Anfrage, die gestellt wird, wenn der Fokus gesperrt ist, AUDIOFOCUS_REQUEST_DELAYED zurück. Wenn die Bedingung, die den Audiofokus gesperrt hat, nicht mehr vorhanden ist, z. B. wenn ein Anruf beendet wird, gewährt das System die ausstehende Fokusanforderung und ruft onAudioFocusChange() auf, um Ihre App zu benachrichtigen.
Um den verzögerten Fokusgewinn zu verarbeiten, müssen Sie einen
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 von einer anderen App berücksichtigt werden kann, die derzeit den Fokus hat und Audioinhalte wiedergibt:
- Fordern Sie permanenten Audiofokus (
AUDIOFOCUS_GAIN) an, wenn Sie Audioinhalte für die absehbare Zukunft wiedergeben möchten (z. B. beim Abspielen von Musik) und Sie erwarten, dass die vorherige App die Wiedergabe beendet. - Fordern Sie vorübergehenden Fokus (
AUDIOFOCUS_GAIN_TRANSIENT) an, wenn Sie Audioinhalte nur für kurze Zeit wiedergeben möchten und erwarten, dass die vorherige App die Wiedergabe pausiert. - Fordern Sie vorübergehenden Fokus mit Ducking (
AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) an, um anzugeben, dass Sie Audioinhalte nur für kurze Zeit wiedergeben möchten und dass die vorherige App die Wiedergabe fortsetzen kann, wenn sie ihre Audioausgabe verringert. Beide Audioausgaben werden in den Audiostream gemischt. Ducking ist besonders für Apps geeignet, die den Audiostream nur zeitweise verwenden, z. B. für hörbare Wegbeschreibungen.
Die requestAudioFocus() Methode erfordert auch einen AudioManager.OnAudioFocusChangeListener. Dieser Listener sollte in derselben Aktivität oder demselben Dienst erstellt werden, zu dem Ihre Mediensitzung gehört. Er implementiert den Callback onAudioFocusChange(), den Ihre App erhält, wenn eine andere App den Audiofokus erhält oder aufgibt.
Das folgende Snippet fordert permanenten Audiofokus für den Stream STREAM_MUSIC an und registriert einen OnAudioFocusChangeListener, 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 }
Rufen Sie nach Abschluss der Wiedergabe
abandonAudioFocus() auf.
Kotlin
audioManager.abandonAudioFocus(afChangeListener)
Java
// Abandon audio focus when playback complete audioManager.abandonAudioFocus(afChangeListener);
Dadurch wird das System benachrichtigt, dass Sie den Fokus nicht mehr benötigen, und der zugehörige OnAudioFocusChangeListener wird abgemeldet. Wenn Sie vorübergehenden Fokus angefordert haben, wird eine App, die pausiert oder die Lautstärke verringert hat, 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
onAudioFocusChange()
Methode im AudioFocusChangeListener
, den Sie angegeben haben, als die App requestAudioFocus() aufgerufen hat.
Der Parameter focusChange, der an onAudioFocusChange() übergeben wird, gibt die Art der Änderung an. Er entspricht dem Hinweis zur Dauer, der von der App verwendet wird, die den Fokus erhält. Ihre App sollte entsprechend reagieren.
- Vorübergehender Verlust des Fokus
-
Wenn die Fokusänderung vorübergehend ist (
AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCKoderAUDIOFOCUS_LOSS_TRANSIENT), sollte Ihre App die Lautstärke verringern (wenn Sie nicht auf automatisches Ducking angewiesen sind) oder die Wiedergabe pausieren, aber ansonsten denselben Zustand beibehalten. - Permanenter Verlust des Fokus
-
Wenn der Verlust des Audiofokus dauerhaft ist (
AUDIOFOCUS_LOSS), gibt eine andere App Audioinhalte wieder. Ihre App sollte die Wiedergabe sofort pausieren, da sie nie einenAUDIOFOCUS_GAIN-Callback erhält. Um die Wiedergabe neu zu starten, muss der Nutzer eine explizite Aktion ausführen, z. B. auf die Wiedergabesteuerung in einer Benachrichtigung oder in der App-UI tippen.
Während eines vorübergehenden Verlusts des Audiofokus sollten Sie weiterhin Änderungen des Audiofokus beobachten und bereit sein, die normale Wiedergabe fortzusetzen, wenn Sie den Fokus wieder erhalten. Wenn die blockierende App den Fokus aufgibt, erhalten Sie einen Callback (AUDIOFOCUS_GAIN). An diesem Punkt können Sie die Lautstärke auf die normale Lautstärke zurücksetzen oder die Wiedergabe neu starten.
Das folgende Code-Snippet zeigt, wie Sie den OnAudioFocusChangeListener und seinen onAudioFocusChange()-Callback implementieren. Beachten Sie die Verwendung eines 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 ein Runnable, das so aussieht:
Kotlin
private var delayedStopRunnable = Runnable { mediaController.transportControls.stop() }
Java
private Runnable delayedStopRunnable = new Runnable() { @Override public void run() { getMediaController().getTransportControls().stop(); } };
Damit der verzögerte Stopp nicht ausgelöst wird, wenn der Nutzer die Wiedergabe neu startet, rufen Sie bei jeder Zustandsänderung mHandler.removeCallbacks(mDelayedStopRunnable) auf. Rufen Sie removeCallbacks() beispielsweise im onPlay(), onSkipToNext() usw. Ihres Callbacks auf. Sie sollten diese Methode auch im onDestroy()-Callback Ihres Dienstes aufrufen, wenn Sie die von Ihrem Dienst verwendeten Ressourcen bereinigen.